JavaScript
vue.js

Vue.js の単一ファイルコンポーネントをプラグインとして作る

めもです。
Vue.js のコンポーネントをプラグインとして開発するための、情報と方法の簡単なまとめです。

tl;dr

app.html
<div id="app">
    <MyComponent />
</div>
app.js
import Vue from 'vue'
import MyComponent from './my-component.vue'

MyComponent.install = function ( VueConstructor ){
  VueConstructor.component( MyComponent.name, MyComponent )
}

Vue.use( MyComponent ) // `MyComponent.install()` が実行される。

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

触れないこと

  • Vue.js と単一ファイルコンポーネントの使い方、作り方
  • JSX, Babel

Vue.js のプラグイン機能

プラグイン — Vue.js https://jp.vuejs.org/v2/guide/plugins.html

Vue.js にはプラグイン機能があり、 ElementUI や Vuetify などのコンポーネントライブラリはこの機構を利用して提供されます。
もちろん公式で提供されている vuexvue-router のようなプラグインも同様です。

プラグインの使用方法、仕組み

使用方法

Vue.js のプラグインをアプリケーション内で利用するには、 Vue.use() メソッドを使用します。

第一引数にプラグインのオブジェクト(又は関数)を渡します。

Vuexの場合
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use( Vuex )

プラグインにオプションが存在する場合は、第二引数にそのオプションを渡してあげます。

ElementUIの場合
import Vue from 'vue'
import Element from 'element-ui'
import locale from 'element-ui/lib/locale/lang/ja'

Vue.use( Element, { locale } )

仕組み

さて、この Vue.js のプラグイン機構ですが、
肝心な部分として、プラグインのオブジェクトをプラグインとして機能させるには
install() というメソッドを定義してあげる必要があります。

MyPlugin.install = function ( Vue, option ) {
    // foobar
}

このメソッドの第一引数には Vue コンストラクタを取り、第二引数 (option) では use() の第二引数に渡した値を受け取ります。
option は上の ElementUI の例で言う所の { locale } が該当します。

Vue.use() に何らかのオブジェクトを渡すと install() の実行が試みられるので、この install() 内でプラグインの初期化処理を行うという訳です。

なお Vue.use() の第一引数に対して Object ではなく関数が渡されると、関数自体をインストーラーと見做して実行するようです。…まだ試したことは無いです。
(参照: https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js#L17

プラグインとしてのコンポーネント

Vue.js プラグインの仕組みが分かったので、コンポーネントライブラリのように Vue.use() して利用するコンポーネントの作り方です。
特に難しいことは無くて、例に倣ってコンポーネントに対して install() メソッドを実装してあげるだけです。

以下で紹介するのは、次の両方での利用が可能なプラグインのコードのイメージです。

  • Vue.use() でグローバルコンポーネントとして登録して利用する。
  • グローバルに登録せず、 インスタンス毎で利用する。
my-component.vue
<template>
    <div class="my-component">
        foobar
    </div>
</template>

<script>
export default {
  name: 'MyComponent',
  mounted () {
    this.$nextTick(() => {
        alert( 'mounted!!' )
    })
  }
}
</script>
installer.js
import MyComponent from './my-component.vue'

MyComponent.install = function (Vue) {
  Vue.component( MyComponent.name, MyComponent )
}

export default MyComponent
app.js
import Vue from 'vue'
import MyComponent from './installer.js'

Vue.use( MyComponent )

// または

new Vue({
  el: '#app',
  components: {
    MyComponent
  }
})

こんな感じになります。


外部に公開したり複数プロジェクトで使い回す予定がなくても、
プラグインという形式でまとまった機能を作り、アプリケーション全体で共通して利用するというのも良さそうですね。