Vue.js の勉強が着々と進み Mixin (ミックスイン) を覚えましたため、使い方をまとめます。

mixin とは

mixin とは Vue.js が提供する「再利用のための仕組」みです。

公式から引用します。

ミックスイン (mixin) は、Vue コンポーネントに再利用可能で柔軟性のある機能を持たせるための方法です。 ミックスインオブジェクトは任意のコンポーネントオプションを含むことができます。
コンポーネントがミックスインを使用するとき、ミックスインの全てのオプションはコンポーネント自身のオプションに”混ぜられ”ます。

Vue.js > ガイド > ミックスイン
https://jp.vuejs.org/v2/guide/mixins.html

mixin はとても簡単に使うことができます。
サンプルをご覧ください。

サンプル

ゴール

クライアントサイドレンダリングでよくある「初回レンダリングまでのローディング表示」を実装します。 要するにスピナーです。

API へコンテンツを取得しに行っている間は Loading バーを表示し、

Loadingバー表示中 イメージ
Loadingバー表示中 イメージ

コンテンツ取得ができたら Loding バーを非表示とし、コンテンツ表示に切り替えます。

Loading終了イメージ
Loading終了イメージ

なお、上記は開発中の Web アプリの画面です。

環境

  • Vue.js 2.2.x
  • Node.js 7.7.x
  • mpn 4.5.x

Beforeコード

1<template>
2  <div>
3    <loading-bar   v-if=" !isLoaded " />
4    <page-contents v-else />
5  </div>
6</template>
 1<script>
 2export default {
 3  created() {
 4    this.fetchItem(this.$route.params.id)
 5  },
 6  data() {
 7    return {
 8      contents: {},
 9      isFinishedLoad: false
10    }
11  },
12  computed: {
13    isLoaded() {
14      return this.isFinishedLoad
15    }
16  },
17  methods: {
18    setFinishedLoad(flg) {
19      this.isFinishedLoad = flg
20    },
21    fetchItem(id) {
22      this.$http({
23        url: '/api/book/'+ id,
24        method: 'GET'
25      }).then(res =>  {
26        this.book = res.data.book
27        this.setFinishedLoad(true)
28      })
29    }
30  },
31  components: {
32    'loading-bar'  : Vue.extend(require('./LoadingBar.vue')),
33    'page-contents': Vue.extend(require('./Content.vue'))
34  }
35}
36</script>
37

フラグを用意して、フラグによって画面が切り替わるというシンプルな仕組みです。
fetchItems() で API レスポンスを受け取った時にフラグを立てます。

たくさんのことをやろうとしているため、コードの可読性は良くありませんね。

Afterコード

Loading バー表示に関わる処理を mixin 化し、メイン処理から追い出しましょう。

次のようにLoadingFlg.vueを作成します。

 1<script>
 2export default {
 3  data() {
 4    return {
 5      isFinishedLoad: false
 6    }
 7  },
 8  computed: {
 9    isLoaded() {
10      return this.isFinishedLoad
11    }
12  },
13  methods: {
14    setFinishedLoad(flg) {
15      this.isFinishedLoad = flg
16    }
17  }
18}
19</script>
20

最初のコードから、mixin 化した部分をカットし、かわりにmixinsを定義します。

 1<script>
 2export default {
 3  created() {
 4    this.fetchItem(this.$route.params.id)
 5  },
 6  data() {
 7    return {
 8      contents: {}
 9    }
10  },
11  methods: {
12    fetchItem(id) {
13      this.$http({
14        url: '/api/book/'+ id,
15        method: 'GET'
16      }).then(res =>  {
17        this.book = res.data.book
18        this.setFinishedLoad(true)
19      })
20    }
21  },
22  components: {
23    'loading-bar'  : Vue.extend(require('./LoadingBar.vue')),
24    'page-contents': Vue.extend(require('./Content.vue'))
25  },
26  mixins: [
27    Vue.extend(require('./LoadingFlg.vue')),
28  ]
29}
30</script>
31

これだけで mixin 化する処理はおしまいです。

フラグを更新する処理は残ってしまいましたが、関心の薄いコードを外部に出すことができてコードがずっと見やすくなりました。

おわりに

mixin とはざっくり言えばクラスを継承するイメージなのですが、Java の継承とな違ってなんとなくスッキリしない感があります。

mixin はコードの再利用に欠かせない仕組みであり大変便利なのですが、あまり多用するとわけがわからなくなっしまうと感じました。

チームで開発する場合には特にこの辺りのルール決めが大切ではないかと感じます。

WEB+DB PRESS Vol.97

外村 和仁,小林 徹,古川 陽介,佐藤 歩,yoku0825,是澤 太志,一野瀬 翔吾,加藤 颯史,のざき ひろふみ,うらがみ,水嶋 淳貴,久田 真寛,久保 達彦,伊藤 直也,遠藤 雅伸,ひげぽん,海野 弘成,はまちや2,竹原,倉岡 洋義
出版社:技術評論社  発売日:2017-02-24

Amazonで詳細を見る

Vue.js入門 基礎から実践アプリケーション開発まで

川口 和也,喜多 啓介,野田 陽平,手島 拓也,片山 真也
出版社:技術評論社  発売日:2018-09-22

Amazonで詳細を見る

基礎から学ぶ Vue.js

mio
出版社:シーアンドアール研究所  発売日:2018-05-29

Amazonで詳細を見る