Vue で共通コードをミックスインにまとめる実例

さてさて、先日本業の開発の方で過去バージョンのVueを互換性に問題がなさそうだったので最新のものに変更したら、実行速度がとても早くなったので感動をしました。

そして、この一件があった時に「そういえば最近このブログでVueの話題を扱ってないな」と思ったので今回はVueの基本的な内容「ミックスイン」の使い方を順を追って紹介することにしました。(シンプルな理由ですみません😂)

ミックスインとは、Vueにはじめから備わっている機能で、簡単に言うと「必要な部分だけ使い回しができる機能」です。

例えば、以下のように数字を3桁カンマに変換するメソッドを作る場合があると思いますが、このnumberFormat()というメソッドは別の場所でもよく使いそうですよね。

new Vue({
    el: '#app',
    methods: {
        numberFormat: function(price) {

            // 例: 1000 → 1,000
            return price.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')

        }
    }
});

そんな場合にこのnumberFormat()だけ別のところに書いていて後でいつでもVueの中へ呼び出すようにできる、それが「ミックスイン」です。

では実際の手順を見てみましょう!

実行環境: Google Chrome 74、Vue 2.6

ミックスインの専用ファイルを作成する

まずは、先ほどのnumberFormat()を専用のファイルに格納します。
ファイル名はそのままnumberFormat.jsでもいいですが、後でまた別の使い「回しメソッド」が入ってきてもいいようにutility.jsとすることにします。

では、/js/vue/mixins/utility.jsというファイルを作成します。(※ パスは私の好みです。もちろんご自身で変更して問題ありません)

そして、中身を以下のようにして保存してください。

var utilityMixin = {
    methods: {
        numberFormat: function(price) {

            return price.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')

        }
    }
};

utilityMixinという名前もご自身でお好きな名前に変更しても問題ないですが、この変数を後で呼び出すことになりますので覚えておいてください。

作成したミックスインをVueで呼び出す

使い方は簡単で、作成したミックスイン・ファイルをscriptタグで呼び出してmixinsの中に配列で入れてあげるだけです。

<html>
<body>
    <div id="app">
        @{{ numberFormat(1000) }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
    <script src="/js/vue/mixins/utility.js"></script>
    <script>

        new Vue({
            el: '#app',
            mixins: [utilityMixin]
        });

    </script>
</body>
</html>

こうすることでどこからでも好きなページからnumberFormat()が呼び出せるというわけです。

mixinsにセットするのがめんどうな場合

先ほどの例で言うと、mixinsパラメータに配列としてミックスインをセットしましたが、毎回これを行うのはめんどうですよね。

そんな場合は、先ほどのutility.jsを次のように変更するといいでしょう。

Vue.mixin({
    methods: {
        numberFormat: function(price) {

            return price.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')

        }
    }
});

こうすると、以下のようにutility.jsを呼び出すだけでnumberFormat()が利用できるようになります。

<script src="/js/vue/mixins/utility.js"></script>
<script>

    new Vue({
        el: '#app',

        // mixinsは不要!

    });

</script>

ただし、一点だけ注意点があります。

それは、Vue.mixin()を使った(グローバル設定した)場合、Vueのインスタンスが作成されるたびにmountedcreatedが呼ばれるという点です。

例えば、以下のようなグローバル設定のミックスインがあったとします。

Vue.mixin({
    mounted: function() {

        console.log("test");

    }
});

そして、次のようにVueインスタンスを2つ作成すると、先ほどのmountedは2回実行され、コンソールには2回「test」と表示されることになります。

<html>
<body>
    <div id="app"></div>
    <div id="sidebar"></div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script>
    <script src="/js/vue/mixins/utility.js"></script>
    <script>

        new Vue({
            el: '#app'
        });

        new Vue({
            el: '#sidebar'
        });

    </script>
</body>
</html>

もちろん気にならないようでしたら問題はないですが、もしmountedで毎回重たい処理をしている場合はページの表示速度が落ちてしまうので、その場合はmixins: [] で指定することをおすすめします。

ミックスインはいろんな機能に対応している

すでに少し紹介しましたが、Vueのミックスインはmethods以外の機能にも対応しています。

例えば、以下のようなcomputedにすればtodayから今日の日付を取得できますし、

Vue.mixin({
   computed: {
        today: function() {

            var now = new Date();
            return now.getFullYear()+'-'+(now.getMonth()+1)+'-'+now.getDate();

        }
    }
});
<span v-text="today"></span>

また、mountedwatchにも対応しています。

Vue.mixin({

    // 省略

    watch: {
        userId: function() {

            // ここで何か

        }
    },
    mounted: function() {

        // ここで何か

    }
});

そして、もちろんdataにも対応しているのですが、ここは注意が必要でdataの場合は通常のVueのようなオブジェクトではなく、関数の返り値として設定しなければいけません。

実際の例を見てみましょう。

Vue.mixin({
    data: function() {

        return {
            userId: 1,
            name: '山田太郎'
        }

    },

    // 省略

});

※ これはコンポーネントの場合も同じです。

こうすることで、あたかも以下のように設定したのと同じような動きをVueにとらせることができるようになります。

new Vue({
    el: '#app',
    data: {
        userId: 1,
        name: '山田太郎'
    }
});

そのため、例えばログインしているユーザーのIDを格納するuserIdなどを専用のミックスインにもたせてもいいかもしれません。

おわりに

ということで、今回は本当にVueにとって基本的な機能ミックスインの使い方を紹介しました。

このブログ記事でよく書いていますが、「いかに開発効率を上げるか?」は「いかに使いまわしをしてるか?」が大きく影響してくると思いますので、普段からよく使うメソッドなどはひとまとめにして、いつでもどのプロジェクトにも使えるようにしておくといいかもしれません。

ちなみに私の場合は、(もちろんOKな場合だけですが)ミックスインやコンポーネントを使いまわしできる形にしてGithubで公開し、いつでもnpmなどでインストールできるようにしています。

ぜひ皆さんも参考にしてみてくださいね。

ではでは〜!