ここでは、現時点の最新版である Vue.js 2.5.13 をベースに説明します。
Vue を用いて Hello world! を表示する例を示します。#app-1 の要素に対して Vue を適用します。Vue が適用された要素内では、{{ message }} などの表記が、JavaScript 側で保持する変数の値に置換されます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue TEST</title> <!-- Vue.js を読み込む --> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app-1">{{ message }}</div> <!-- {{ message }} が Vueデータに置換される --> <script> var app1 = new Vue({ el: '#app-1', /* #app-1 要素に対して Vue を適用する */ data: { message: 'Hello world!' } /* message という名前のデータを定義する */ }) </script> </body> </html>
もう少し、実用的な Vue の利用例を紹介しておきます。下記の例では、フォームに入力した文字が、1文字に満たなければ「必須項目です。」、5文字より長ければ「長すぎます」のエラーメッセージを表示します。
<style> #app-2 .error { color: red; } </style> <div id="app-2"> <input type="text" v-model="message"> <div class="error" v-if="error.require">必須項目です。</div> <div class="error" v-if="error.tooLong">長すぎます。</div> </div> <script> var app2 = new Vue({ el: '#app-2', watch: { message: function(newVal, oldVal) { this.error.require = (newVal.length < 1) ? true : false; this.error.tooLong = (newVal.length > 5) ? true : false; } }, data: { message: 'Hello', error: { require: false, tooLong: false } } }) </script>
CDN で公開されているライブラリを使用します。
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
下記からライブラリをダウンロードします。開発バージョン、本番バージョンがありますが、開発バージョンでは詳細はログを出力したり、デバッグ機能を利用できたりします。
<script src="./lib/vue.js"></script> // 開発バージョン <script src="./lib/vue.min.js"></script> // 本番バージョン
npm を使用する環境では、下記の様にしてインストールします。
$ npm install vue
node_modules/vue/dist フォルダの下に下記のファイルがインストールされます。
バージョン | UMD | CommonJS | ES Module | |
---|---|---|---|---|
開発バージョン | フル版 | vue.js | vue.common.js | vue.esm.js |
ランタイム版 | vue.runtime.js | vue.runtime.common.js | vue.runtaime.esm.js | |
本番バージョン | フル版 | vue.min.js | ||
ランタイム版 | vue.runtime.min.js |
開発バージョン には、詳細ログ出力などのデバッグ支援機能が含まれていますが、本番バージョン には含まれていません。フル版 には、template: '<div>{{ msg }}</div>' などの文字列をコンパイルして展開する機能が含まれていますが、ランタイム版 には含まれていません。<script> でブラウザから直接使用する場合は UMD 版を使用します。browserify や webpack 1 などの古いバンドラでは CommonJS 版を、webpack 2 や rollup などの新しいバンドラでは ES Module 版を使用します。
Vue では、タグに v-* の属性を指定することができます。これを ディレクティブ と呼びます。下記で説明するものの他、Vue.directive() や directives で独自のカスタムディレクティブを定義することもできます。
v-text は包含するテキストのデータ名を指定します。
<div id="app-101"> <div v-text="message"></div> <!-- この行と --> <div>{{ message }}></div> <!-- この行は、同じ意味を持ちます --> </div> <script> var app101 = new Vue({ el: '#app-101', data: { message: 'Hello!' } }) </script>
通常のテキストは、<, >, & が <, >, & に置換されて出力されますが、v-html を用いた場合はタグがそのまま出力されます。迂闊に使用するとセキュリティ問題を起こすことがあるので、クロスサイトスクリプティングに注意しながら使用してください。
<div id="app-102"> <div v-text="message"></div> <!-- 置換される --> <div v-html="message"></div> <!-- 置換されない --> </div> <script> var app102 = new Vue({ el: '#app-102', data: { message: '<b>Hello!</b>' } }) </script>
v-show は、値の真偽により表示する・しないを制御します。下記の例では、変数 seen が true の時は Hello! を表示し、false の時は表示しません。v-if が要素自体の有無を制御するのに対し、v-show では CSS の display プロパティで表示のみを制御します。
<div id="app-103"> <input type="checkbox" @click="change" checked> <span v-show="seen">Hello!</span> </div> <script> var app103 = new Vue({ el: '#app-103', data: { seen: true }, methods: { change: function(e) { this.seen = e.target.checked } } }) </script>
v-if は、値の真偽により描画する・しないを制御します。下記の例では、変数 seen が true の時は Hello! を描画し、false の時は描画しません。v-show が CSS の display プロパティで表示のみを制御するのに対し、v-if では要素自体の有無を制御します。
<div id="app-104"> <input type="checkbox" @click="change" checked> <span v-if="seen">Hello!</span> </div> <script> var app104 = new Vue({ el: '#app-104', data: { seen: true }, methods: { change: function(e) { this.seen = e.target.checked } } }) </script>
v-else は v-if と組み合わせて使用し、「さもなくば」を実装します。下記の例では、seen が true の時は Hello! を、さもなくば Bye! を表示します。
<div id="app-105"> <input type="checkbox" @click="change" checked> <span v-if="seen">Hello!</span> <span v-else>Bye!</span> </div> <script> var app105 = new Vue({ el: '#app-105', data: { seen: true }, methods: { change: function(e) { this.seen = e.target.checked } } }) </script>
v-else-if は v-if と組み合わせて使用し、「さもなくばもし」を実装します。下記の例では type が A の時は Good morining. を、B の時は Hello! を、さもなくば Bye! を表示します。
<div id="app-106"> <input type="radio" name="app106-type" onclick="app106.type='A'" checked> <input type="radio" name="app106-type" onclick="app106.type='B'"> <input type="radio" name="app106-type" onclick="app106.type='C'"> <span v-if="type=='A'">Good morning.</span> <span v-else-if="type=='B'">Hello!</span> <span v-else>Bye!</span> </div> <script> var app106 = new Vue({ el: '#app-106', data: { type: 'A' } }) </script>
v-for はオブジェクトを配列の個数分表示したりなどのループに使用します。
<div id="app-107"> <ul> <li v-for="color in colorList">{{ color }}</li> </ul> </div> <script> var app107 = new Vue({ el: '#app-107', data: { colorList: [ 'Red', 'Green', 'Blue' ] } }) </script>
v-on はイベントを処理します。@ は v-on: の省略形です。v-on:click= と @click は同じ意味を持ちます。
<div id="app-108"> <button v-on:click="hello">Hello</button> <button @click="hello">Hello</button> </div> <script> var app108 = new Vue({ el: '#app-108', methods: { hello: function() { alert("Hello!"); } } }) </script>
v-on には、v-on:click.once や @click.once の様に、いくつかの修飾子をつけることができます。
修飾子 | 説明 |
---|---|
.stop | event.stopPropagation() を呼び、イベントが親要素に伝播するのを抑止します。 |
.prevent | event.preventDefault() を呼び、デフォルトの動作を抑止します。 |
.capture | イベントリスナをキャプチャモードで追加します。 |
.self | イベントがこの要素からディスパッチされた場合のみハンドラを呼びます。 |
.{keyCode | keyAlias} | 指定されたキーが押された時のみ、ハンドラを呼びます。 |
.native | コンポーネントのルート要素に対するネイティブイベントを監視します。 |
.once | 一度だけハンドラを呼びます。 |
.left | (2.2.0+) マウスの左ボタンに対してのみ、ハンドラを呼びます。 |
.right | (2.2.0+) マウスの右ボタンに対してのみ、ハンドラを呼びます。 |
.middle | (2.2.0+) マウスの中ボタンに対してのみ、ハンドラを呼びます。 |
.passive | (2.3.0+) { passive: true } で DOM イベントをアタッチします。 |
v-bind は、HTML タグの属性値に変数名を割り当てます。: は v-bind: の省略系です。v-bind:属性名 と :属性名は同じ意味を持ちます。
<div id="app-109"> <input type="button" v-bind:value="message"> <input type="button" :value="message"> </div> <script> var app109 = new Vue({ el: '#app-109', data: { message: 'Hello!' } }) </script>
v-bind には、v-bind:value.camel や :value.camel の様に、いくつかの修飾子をつけることができます。
修飾子 | 説明 |
---|---|
.prop | 属性の代わりに DOM プロパティをバインドします。 |
.camel | (2.1.0+) ケバブケース(例:color-name)の属性名を、キャメルケース(例:ColorName)の属性名に変換します。 |
.sync | バインドされた値を更新する v-on ハンドラに展開されるのと同じ構文となります。 |
v-model は、input, select, textarea に対して使用し、Vue オブジェクトのデータと、フォーム部品の値を関係づけます。
<div id="app-120"> <input v-model="message"> <div>Message: {{ message }}</div> </div> <script> var app120 = new Vue({ el: '#app-120', data: { message: 'Hello!' } }) </script>
v-model には、v-model.trim のように、いくつかの修飾子をつけることができます。
修飾子 | 説明 |
---|---|
.lazy | input の代わりに change イベントを監視します。 |
.number | データを数値に変換します。 |
.trim | データをトリム(前後の空白を取り去る) |
v-pre は、Vue 対象の要素の中で、{{ ... }} を直接表示したい場合に使用します。
<div id="app-121"> <div v-pre>Message: {{ message }}</div> <div>Message: {{ message }}</div> </div> <script> var app121 = new Vue({ el: '#app-121', data: { message: 'Hello' } }) </script>
v-cloak は、画面を開いた際に {{ ... }} が一瞬だけ表示されてしまうのを防ぎます。cloak には、マントを着せるとか、覆い隠すという意味があります。v-cloak 属性が指定された要素に対してあらかじめ CSS の display: none を適用しておきます。Vue のレンダリングが終わった時点で自動的に display: none が解除されます。下記の例では、1秒だけ Vue の処理実行を遅らせています。v-cloak を指定しない場合は {{ message }} が 1秒程度表示されてしまうのに対し、v-cloak を指定した場合は表示が抑制されるのがわかります。
<style> [v-cloak] { display: none } </style> <div id="app-122"> <button onclick="location.reload()">再表示</button> <div>Message: <span v-cloak>{{ message }}</span></div> <div>Message: <span>{{ message }}</span></div> </div> <script> window.setTimeout(function() { var app122 = new Vue({ el: '#app-122', data: { message: 'Hello!' } }) }, 1000); </script>
v-once は、Vue によるレンダリングを1度だけ行い、それ以降は変数が変動しても、表示に反映しないことを指示します。
<div id="app-123"> <input type="text" name="text1" v-model:value="message"> <div>Message: <span v-once>{{ message }}</span></div> <div>Message: <span>{{ message }}</span></div> </div> <script> var app123 = new Vue({ el: '#app-123', data: { message: 'Hello' } }) </script>
Vue.component() は、コンポーネントと呼ばれる Vue の独自要素を定義します。下記の例では、'<strong>Hello!</strong>' を表示する独自要素 <my-element-140> を定義しています。
<div id="app-140"> <my-element-140></my-element-140> </div> <script> Vue.component('my-element-140', { template: '<strong>Hello</strong>' }) var app140 = new Vue({ el: '#app-140', }) </script>
Vue.extend() は、Vue.component() の第二引数で指定可能な、コンポーネントのサブクラスを生成します。
<div id="app-141"> <my-component-141></my-component-141> </div> <script> var MyComponent141 = Vue.extend({ template: '<strong>Hello!</strong>' }) Vue.component('my-component-141', MyComponent141) var app141 = new Vue({ el: '#app-141', }) </script>
Vue.nextTick() は、一連の DOM 更新サイクル完了後に実行すべきコールバック関数を登録します。下記の例では、app142.message を変更した直後ではまだ DOM は更新されておらず、コンソールには Hello! が出力されます。nextTick() で登録したコールバック関数は、DOM 更新サイクル終了後に呼び出されるため、DOM の情報も Bye! に更新されていることが確認できます。
<div id="app-142"> <div>{{ message }}</div> </div> <script> var app142 = new Vue({ el: '#app-142', data: { message: 'Hello!', msg1: '', msg2: '' } }) app142.message = 'Bye!' console.log(app142.$el.textContent); Vue.nextTick(function() { console.log(app142.$el.textContent); }) </script>
Vue.set() は、オブジェクトのプロパティを設定し、必要に応じて View の更新を行います。Vue では、data で指定された各データに対して内部的に getter/setter を用意し、データの変更を監視し、View に反映します。これをリアクティブなデータと呼びます。しかし、データ内部のプロパティが追加・削除された場合はその変更を検出することができません。下記の例では、this.colorList.blue = '#00f' としてプロパティを追加する代わりに、Vue.set() を用いて追加することにより、Vue にデータの変更を認識させ、View へ反映させています。
<div id="app-143"> <input type="button" @click="addBlue" value="Add"> <input type="button" @click="deleteBlue" value="Delete"> <ul> <li v-for="(value, key) in colorList">{{ key }} = {{ value }}</li> </ul> </div> <script> var app143 = new Vue({ el: '#app-143', data: { colorList: { red: '#f00', green: '#0f0' } }, methods: { addBlue: function() { Vue.set(this.colorList, 'blue', '#00f') }, deleteBlue: function() { Vue.delete(this.colorList, 'blue') } } }) </script>
Vue.delete() は、Vue.set() と同様に、非リアクティブなデータを削除するために用います。使用例は Vue.set() を参照してください。
v-for や v-show などの ディレクティブ に加えて、グローバルに独自のカスタムディレクティブを追加することができます。下記の例では、フォントサイズを 16pt にする v-font16 カスタムディレクティブを作成しています。ローカルなカスタムディレクティブを作成するには directives オプションを参照してください。
<div id="app-144"> <div v-font16>Hello!</div> </div> <script> Vue.directive('font16', { inserted: function(el) { el.style.fontSize = '16pt' } }) var app144 = new Vue({ el: '#app-144' }) </script>
{{ 変数名 }} の箇所には、{{ 変数名 | フィルタ1 | フィルタ2 }} のようにいくつかのフィルタを記述することができます。下記の例では、Vue.filter() を用いて toupper フィルタを定義しています。ローカルなフィルタを登録するには filters を参照してください。
<div id="app-145"> <div>{{ message | toupper }}</div> </div> <script> Vue.filter('toupper', function(value) { return value.toUpperCase() }) var app145 = new Vue({ el: '#app-145', data: { message: 'Hello!' } }) </script>
Vue.use() は、プラグインを利用する際に呼び出します。
Vue.use(MyPlugin)
グローバルミックスインを定義します。ミックスインについての詳細は mixins を参照してください。
<script> Vue.mixin({ created: function() { console.log(this) } }) </script>
Vue.compile() は、{{ message }} などの文字列をあらかじめコンパイルします。
<script> var res = Vue.compile('<div>{{ message }}</div>'); new Vue({ data: { message: 'Hello!' }, render: res.render, staticRenderFns: res.staticRenderFns }) </script>
Vue.version は、Vue のバージョン番号を返します。
<script>
console.log(Vue.version) <!-- 2.5.13 -->
</script>
data は、{{ ... }}, v-bin, v-model などで参照されるデータを保持します。
<div id="app-201">{{ message }}</div> <script> var app201 = new Vue({ el: '#app-201', data: { message: 'Hello!' } }) </script>
props は、template などのコンポーネント内部で使用する属性を定義します。下記の例では、<my-element-202> の value 属性に対して、props で宣言することによって、template の内部で value の値を参照することが可能となります。
<div id="app-202"> <my-element-202 value="Hello!"></my-element-202> </div> <script> Vue.component('my-element-202', { props: [ 'value' ], template: '<div>{{ value }}</div>' }) var app202 = new Vue({ el: '#app-202' }) </script>
インスタンス作成中の props データを指定します。主に、Vue の単体テストを支援するために用いられます。
<div id="app-203"> <div id="el-203"></div> </div> <script> var MyElement203 = Vue.extend({ props: [ 'message' ], template: '<div>{{ message }}</div>' }) var vm = new MyElement203({ propsData: { message: 'Hello!' } }).$mount('#el-203'); var app203 = new Vue({ el: '#app-203' }) </script>
computed は算出プロパティを生成します。下記の例では、message プロパティを元に、それを大文字化した upperMessage プロパティを算出して表示しています。
<div id="app-204"> <div><input v-model="message"></div> <div>Message: {{ upperMessage }}</div> </div> <script> var app204 = new Vue({ el: '#app-204', data: { message: 'Hello' }, computed: { upperMessage: function() { return this.message.toUpperCase(); } } }) </script>
methods は、v-on のイベントハンドラとして呼び出されるメソッドを定義します。
<div id="app-205"> <button @click="toUpper">Upper</button> <button @click="toLower">Lower</button> <div>{{ message }}</div> </div> <script> var app205 = new Vue({ el: '#app-205', data: { message: 'Hello' }, methods: { toUpper: function() { this.message = this.message.toUpperCase(); }, toLower: function() { this.message = this.message.toLowerCase(); } } }) </script>
watch は、データの変動を監視します。データ変動時にコールバック関数が呼ばれ、引数には変更前の値と、変更後の値が渡されます。
<div id="app-206"> <form> <input type="text" name="text1" :value="message"> <input type="button" @click="change" value="Change"> </form> <div>変更前: {{ oldmsg }}</div> <div>変更後: {{ newmsg }}</div> </div> <script> var app206 = new Vue({ el: '#app-206', data: { message: 'new', newmsg: 'new', oldmsg: 'old' }, watch: { message: function(newVal, oldVal) { this.newmsg = newVal; this.oldmsg = oldVal; } }, methods: { change: function(e) { this.message = e.target.form.text1.value; } } }) </script>
el には、Vue を適用する要素を指定します。CSS のセレクタの構文を使用することができます。
<div id="app-210" v-text="message"></div> <script> var app210 = new Vue({ el: '#app-210', data: { message: 'Hello!' } }) </script>
template には、コンポーネントのテンプレートを指定します。
<div id="app-211"> <my-element-211></my-element-211> </div> <script> Vue.component('my-element-211', { template: '<span>Hello!</span>' }) var app211 = new Vue({ el: '#app-211', }) </script>
render は、template では表現できない複雑なテンプレートを、JavaScript の関数を用いて定義します。下記の例では、level 属性で指定した値によって、h1~h6 を適用する例を示しています。
<div id="app-212"> <my-heading-212 :level="1">Hello!</my-heading-212> </div> <script> Vue.component('my-heading-212', { render: function (createElement) { return createElement('h' + this.level, this.$slots.default) }, props: [ 'level' ] }) var app212 = new Vue({ el: '#app-212', }) </script>
renderError は、開発モードでのみ有効で、render 関数内でエラーが発生した際に、エラー詳細情報などを表示するために用いられます。下記の例では、render 関数で throw された例外を受け取り、renderError 関数でスタック情報を表示しています。
<div id="app-213"> <app213-heading :level="1">Hello!</app213-heading> </div> <script> Vue.component('app213-heading', { render: function (createElement) { throw new Error('err213') }, renderError : function(ce, err) { return ce('pre', { style: { color: 'red' }}, err.stack) }, props: [ 'level' ] }) var app213 = new Vue({ el: '#app-213', }) </script>
Vue のインスタンスが生成されたり、更新されたりする際に呼ばれるコールバック関数を指定します。
<script> new Vue({ created: function() { console.log(this) } }) </script>
下記のフック関数が定義されています。
フック関数 | 説明 |
---|---|
beforeCreate | インスタンスが作成される直前に呼ばれます。 |
created | インスタンスが作成された直後に呼ばれます。 |
beforeMount | render によってマウントされる直前に呼ばれます。 |
mounted | render によってマウントされた直後に呼ばれます。 |
beforeUpdate | インスタンスのデータが更新される直前に呼ばれます。 |
updated | インスタンスのデータが更新された直後に呼ばれます。 |
activated | コンポーネントが活性化する時に呼ばれます。 |
deactivated | コンポーネントが非活性化する時に呼ばれます。 |
beforeDestroy | インスタンスが破棄される直前に呼ばれます。 |
destroyed | インスタンスが破棄された直後に呼ばれます。 |
errorCaptured | エラーがキャプチャされた時に呼ばれます。 |
v-for や v-show などの ディレクティブ に加えて、ローカルに独自のカスタムディレクティブを追加することができます。下記の例では、フォントサイズを 16pt にする v-font16 カスタムディレクティブを作成しています。グローバルなカスタムディレクティブを作成するには Vue.directive() を参照してください。
<div id="app-250"> <div v-font16>Hello!</div> </div> <script> var app250 = new Vue({ el: '#app-250', directives: { font16: { inserted: function(el) { el.style.fontSize = '16pt' } } } }) </script>
inserted の他には下記のフック関数を指定することができます。
フック関数 | 説明 |
---|---|
bind | ディレクティブがはじめて要素にバインドされた時に 1度だけ呼ばれます。 |
inserted | 要素が親要素に対して挿入された時に呼ばれます。 |
update | 要素が包含しているコンポーネントの VNode が更新される際に呼ばれます。 |
componentUpdated | 包含しているコンポーネントの VNode および子コンポーネントの VNode が更新された時に呼ばれます。 |
unbind | ディレクティブが要素からアンバインドされた時に呼ばれます。 |
{{ 変数名 }} の箇所には、{{ 変数名 | フィルタ1 | フィルタ2 }} のようにいくつかのフィルタを記述することができます。下記の例では、filters を用いて toupper フィルタと tolower フィルタを定義しています。グローバルなフィルタを登録するには Vue.filter() を参照してください。
<div id="app-251"> <div>{{ message | toupper }}</div> <div>{{ message | tolower }}</div> </div> <script> var app251 = new Vue({ el: '#app-251', data: { message: 'Hello!' }, filters: { toupper: function(value) { return (value.toUpperCase()) }, tolower: function(value) { return (value.toLowerCase()) } } }) </script>
components には、事前に定義したコンポーネントの一覧を設定します。
<div id="app-252"> <my-comp1></my-comp1> <my-comp2></my-comp2> <my-comp3></my-comp3> </div> <script> var MyComp1 = { template: '<div style="color:red">Hello!</div>' } var MyComp2 = { template: '<div style="color:green">Hello!</div>' } var MyComp3 = { template: '<div style="color:blue">Hello!</div>' } var app252 = new Vue({ el: '#app-252', components: { 'my-comp1': MyComp1, 'my-comp2': MyComp2, 'my-comp3': MyComp3 } }) </script>
ミックスインは、ライブラリの様に取り込んで利用することが可能な部品です。下記の例では、hello というメソッドを持つ myMixin を定義し、それを mixins で取り込んでいます。
<div id="app-261"> <input type="button" @click="hello" value="Hello"> </div> <script> var myMixin = { methods: { hello: function() { alert("Hello!"); } } } var app261 = new Vue({ el: '#app-261', mixins: [ myMixin ] }) </script>
Vue.config.silent を true にすると、Vue のログや警告の出力を抑止します。
Vue.config.silint = true
Vue.config.devtools は、開発モードの場合に true, 本番モードの時に false となります。
Vue.config.devtools = true
Vue.config.errorHandler は、エラーが発生した際のエラーハンドラを定義します。err には throw された Error オブジェクト、vm にはエラーが発生した Vue コンポーネント、info には Vue 固有のエラー情報が渡されます。
Vue.config.errorHandler = function(err, vm, info) { ... }
Vue.config.warnHandler は、警告が発生した際の警告ハンドラを定義します。msg には警告メッセージ、vm にはエラーが発生した Vue コンポーネント、trace にはトレース情報が渡されます。
Vue.config.warnHandler = function(msg, vm, trace) { ... }
Vue.config.ignoredElements には、Vue の外部で作成された Webコンポーネント のカスタムタグなどで、無視するものを指定します。正規表現も使用できます。
Vue.config.ignoredElements = [ 'my-custom-web-component', 'another-web-component', /^ion-/ ]
keyCodes には、@keyup 等で使用するキーコードを指定します。下記の例では、Alt-H キーに "alt-h" という名前を割り当て、@keyup で使用しています。Alt-H キーが押された時点でハンドラが呼び出されます。18 は Alt キーの、72 は H キーのキーコードです。ハイフンを含む名前の場合は、"..." で囲んでください。
<div id="app-301"> <input type="text" @keyup.alt-h="help"> </div> <script> Vue.config.keyCodes = { h: 72, "alt-h": [ 18, 72 ] } var app301 = new Vue({ el: '#app-301', methods: { help: function() { alert("Help ..."); } } }) </script>
performance を true にすると、開発者ツールのタイムライン機能で、パフォーマンスデータを詳細に表示することが可能となります。開発モードでのみ使用可能です。
Vue.config.performance = true
productionTip を false にすると、起動時の製品ヒント情報の出力を抑止します。
Vue.config.productionTip = false