Vue.js の勉強が着々と進み Mixin (ミックスイン)
を覚えましたため、使い方をまとめます。
mixin とは
mixin とは Vue.js が提供する「再利用のための仕組」みです。
公式から引用します。
ミックスイン (mixin) は、Vue コンポーネントに再利用可能で柔軟性のある機能を持たせるための方法です。 ミックスインオブジェクトは任意のコンポーネントオプションを含むことができます。
コンポーネントがミックスインを使用するとき、ミックスインの全てのオプションはコンポーネント自身のオプションに”混ぜられ”ます。Vue.js > ガイド > ミックスイン
https://jp.vuejs.org/v2/guide/mixins.html
mixin はとても簡単に使うことができます。
サンプルをご覧ください。
サンプル
ゴール
クライアントサイドレンダリングでよくある「初回レンダリングまでのローディング表示」を実装します。
要するにスピナー
です。
API へコンテンツを取得しに行っている間は Loading バーを表示し、
コンテンツ取得ができたら Loding バーを非表示とし、コンテンツ表示に切り替えます。
なお、上記は開発中の 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>
フラグを用意して、フラグによって画面が切り替わるというシンプルな仕組みです。
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>
最初のコードから、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>
これだけで mixin 化する処理はおしまいです。
フラグを更新する処理は残ってしまいましたが、関心の薄いコードを外部に出すことができてコードがずっと見やすくなりました。
おわりに
mixin とはざっくり言えばクラスを継承するイメージなのですが、Java の継承とな違ってなんとなくスッキリしない感があります。
mixin はコードの再利用に欠かせない仕組みであり大変便利なのですが、あまり多用するとわけがわからなくなっしまうと感じました。
チームで開発する場合には特にこの辺りのルール決めが大切ではないかと感じます。