【Vue】Vue Mixins + TypeScript ~ 入門編 ~

■ はじめに

https://dk521123.hatenablog.com/entry/2021/01/12/000804

の続き。

 今回は、Vue の ミックスイン(Mixin)っていう機能を
TypeScript で実装してみる。

(まだ、ちゃんと理解しきれてないので、徐々にまとめていく。
 ちゃんと理解しないと使わない方がよさそう)

目次

【1】ミックスイン(Mixin)について
【2】使用上の注意
【3】サンプル

【1】ミックスイン(Mixin)について

* コンポーネントに再利用可能な機能を持たせるための方法
* mixin で関数や変数などを定義すれば、
 どのコンポーネントでも「this.$xxxx」の形で呼び出す事ができる

公式サイト
https://jp.vuejs.org/v2/guide/mixins.html
https://012-jp.vuejs.org/guide/extending.html

【2】使用上の注意

https://logmi.jp/tech/articles/321249
https://blog.capilano-fw.com/?p=5727
https://aloerina01.github.io/blog/2018-12-25-1#%E5%A4%B1%E6%95%97%E4%BE%8B1-template-method%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E6%84%8F%E8%AD%98%E3%81%97%E3%81%9Fmixin
https://jp.vuejs.org/v2/guide/mixins.html

などで、言っていることを纏めると、、、
~~~~~~~~~~~~~~
1)コードが煩雑になりやすい
2)名前競合により、意図しないメソッドが発火してしまう恐れあり
 => Override するわけじゃない。
3)Minix にライフサイクルフック(e.g. mountedなど)を定義すると
  各コンポーネント間で呼び出されてしまう
  (意図していればいいけど、、、)
~~~~~~~~~~~~~~
 => 極力、Mixin を使わずに書く方がいい。
  (特に、props や ライフサイクル で使用する際は危険そう)
  => そうなると、Vue Plugin でよくない?

Mixin の 動作仕様
https://jp.vuejs.org/v2/guide/mixins.html

より、
~~~~~~~~~
1)Mixin とコンポーネントで変数名の競合が起きた場合
 ⇒ コンポーネントの値が優先される
2)Mixin とコンポーネントでライフサイクルフックの競合が起きた場合
 ⇒ 両方実行されるが、Mixin が先に実行される
~~~~~~~~~

【3】サンプル

本当は、「vue-mixin-decorator」っていうのをインストールした方が
スマートに実装できるようだが、今回は使わずに実装してみる。

ファイル構成

my-app << 対象プロジェクト
 + src
     + views
      |  + Hello.vue << 新規追加
      + router
      | + index.ts << 修正(Hello.vueを追加。今回は省略)
     + main.ts << 修正
     + HelloMixin.ts << 新規追加

HelloMixin.ts

import { VueConstructor } from 'vue';

declare module 'vue/types/vue' {
  interface Vue {
    /**
     * Hello world!
     * @param name 
     * @returns Hello, <name>
     */
    $getHello(name: string): Promise<string>;
  }
}

export default class {
  static install(Vue: VueConstructor) {
    // グローバル Mixin
    Vue.mixin({
      methods: {
        $getHello: async (name: string) => {
          console.log(`name = ${name}`);
          return `Hello, ${name}`;
        }
      }
    });
  }
}

main.ts

// ・・・略・・・
import HelloMixin from '@/HelloMixin';

Vue.use(HelloMixin);
// ・・・略・・・

Hello.ts

<template>
  <div>
    <div v-show="message">{{ message }}</div>
  <div><button v-on:click="onClick">Click me!</button></div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class Hello extends Vue {
  private message = '';

  onClick() {
    this.$getHello('Mike').then((response) => {
      this.message = response;
    });
  }
}
</script>

動作確認

[1] 以下をコマンドし、サーバを起動させる
~~~~~
npm run server
~~~~~
[2] 以下のURLにアクセスする

http://localhost:8080/Hello

[3] ボタンを順番に押していく
 => 「Hello, Mike」が表示されるはず。。。

参考文献

https://morymory.com/2020/02/02/%E3%80%90vue-js%E3%80%91%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%BC%EF%BC%88filter%EF%BC%89%E3%81%A8%E3%83%9F%E3%83%83%E3%82%AF%E3%82%B9%E3%82%A4%E3%83%B3%EF%BC%88mixin%EF%BC%89/

関連記事

Vue ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/04/30/000000