JavaScript
Vue.js
ECMAScript6
ECMAScript2015
vue-cli

Vue CLI 3プロジェクトにおけるVueインスタンスの初期化を理解する

Vue CLI 3のプロジェクトでひな形をつくると、初期化を担うsrc/main.jsに、つぎのようなVueインスタンスをつくるコードが加わります。普通はとくに気にせず、触らなくて構いません。でも、やはり気になったので、少し調べました。

import Vue from 'vue'

import App from './App.vue'

Vue.config.productionTip = false

new Vue({
render: h => h(App),
}).$mount('#app')

うえのコードは、Vue.jsのなじみのある書き方にすると、つぎのようになるようです。

new Vue({

el: '#app',
// render: h => h(App),
components: {App},
template: '<App/>'
}); // .$mount('#app')

もっとも、実際にこう書き替えると、つぎのような警告が示されます。プロジェクトはランタイムのみのビルドを用いているため、テンプレートのコンパイルが通らないということです。予めテンプレートをコンパイルしておくか、コンパイラが含まれたビルドを使わなければなりません。


[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.


このテンプレートを動的につくるために使うのが描画関数render()です。たとえば、ページに<h1>要素とテキストを差し込むなら、つぎのようにrender()メソッドを定めます。引数にはDOMツリーをつくるための関数(createElement())が渡されます。その戻り値をrender()メソッドから返せばよいのです。

new Vue({

// render: h => h(App),
render(createElement) {
return createElement('h1', 'hello world');
}
}).$mount('#app')

けれど、関数でテンプレートをつくろうとすると、プロパティや入れ子要素など定めるものが多ければ、かなり面倒になります。そこで、引数として替わりに渡せるのが、単一ファイルコンポーネント(.vue)のインスタンスです。

はじめにみたVue CLIプロジェクトのJavaScriptコードは、つぎのように書き改めると、もう少しわかりやすいかもしれません。

new Vue({

// render: h => h(App),
render(createElement) {
return createElement(App);
}
}).$mount('#app')

なお、render()メソッドを使わずに、スプレッド構文Vueインスタンスを渡しても動きました(「When I should use render: h => h(App)?」参照)。

new Vue({

// render: h => h(App),
...App
}).$mount('#app')

ところで、render()メソッドの引数をhとした理由が、Vue.jsのIssues「What does h mean?」で開発者のEvan You氏から明かされています。HTML構造をつくる"Hyperscript"の頭文字で、タイプもしやすいからとのことです(「Render Function API」参照)。


It comes from the term "hyperscript", which is commonly used in many virtual-dom implementations. "Hyperscript" itself stands for "script that generates HTML structures" because HTML is the acronym for "hyper-text markup language".