Vueまとめパート1
こちらの記事は、Adnan Babakan 氏によりDev.to上で公開された『 Vue cheat sheet 1 』の邦訳版です(原著者から許可を得た上での公開です)
原著をベースに説明の足りない部分は適宜、追記していく予定です。
(追記・改変の許可は得ています。)
Dev.toコミュニティのみなさん、こんにちは!
私はVue.jsが大好きで書くのを楽しんでいます。この記事ではVue.jsのほぼすべての基本的な概念(公式Webサイトに基づく)を取り上げています。目次から必要なセクションに簡単にアクセスできます。
このパートではVueコンポーネントについては説明していません。
いくつかのコードサンプルは公式ウェブサイトから引用しています。Vue.jsで確認できます。1
{{ }}
- 展開(Interpolation)
展開とは、VueのMustache構文(二重波括弧{{ }}
)を使ってデータを画面にレンダリングすること。
単純な展開
Mustache構文を使ってデータをレンダリングする。
<span>私の名前は{{ myName }}です。</span>
式を使った展開
Vueでは、展開に単純な式を含めることができる。
単純な式展開
Mustache構文内でJavaScriptの式を使用可能。
<span>私は{{ myAge + 5 }}歳です!</span>
JavaScriptのメソッドを使ってデータを操作し、レンダリングする文字列または整数を返すこともできる。
<span>私のペットたちの名前は{{ myPets.join(", ") }}です。</span>
三項演算子を使った式展開
三項演算子を使用して、単純な条件付きレンダリングが可能。
<span>私は{{ myAge > 50 ? 'シニア' : 'シニアではない' }}です!</span>
注意:
-
Mustache構文内では1つの式しか使用できない
-
式(Expression)は文(Statement)とは異なる。たとえば、次のコードは、式ではなく文なので機能しない。
<!-- これは誤り -->
{{ let msg = 'Hello World!'; }}
- 制御構文は、Mustache構文内ではサポートされていない。
<!-- これは誤り -->
{{ if (true) { return 'Yes!' } }}
生のHTML展開
データをエスケープして実際のHTMLとしてレンダリングしたくない場合は、次のv-html
ディレクティブを使うようにする。2
<span v-html="myHTMLData"></span>
警告:HTMLのレンダリングは、WebサイトへのXSS(クロスサイトスクリプティング)攻撃を引き起こす可能性があるため、危険な場合がある。
v-bind
- バインディング(Binding)
バインディングとは、要素の属性に対してデータを使用すること。
単純なバインディング(Simple binding)
新米Vue開発者がやりがちなのは次のように属性にデータを入れようとすること。
<span class="{{ myClass }}"></span>
しかし、これは間違いで実際にはデータをバインドしないといけない。
<span v-bind:class="myClass"></span>
次のように、:
だけでv-bind
ディレクティブを省略して短く書くことができる。
<span :class="myClass"></span>
文字列連結を使ったバインディング
バインディングする際に文字列とデータを組み合わせる場合はどうするか。その場合は文字列を引用符で囲み、通常どおり連結する。
<span :class="myClass + 'test'"></span>
これはハイパーリンク内で使うととても便利。
<a :href="baseURL + '/post/' + postId">さらに詳しく</a>
これは、ベースURLとpost
サフィックス、post IDを含む投稿へのリンクの良い例。
条件付きバインディング (Conditional binding)
バインディングを使用して、条件付きで何かを行うことができる。
disabled
やrequired
のような値を持たない属性の場合、バインディングされたデータがtrueを返す場合はその属性が要素に追加され、falseを返す場合は属性は追加されない。
<button :disabled="true"></button>
真偽値を返す式を使用することもできる。
<button :disabled="password.length < 6"></button>
条件が満たされた場合だけ指定したクラスをバインドするのに、クラス属性内でオブジェクトを使うことができる。
<div :class="{green: true, red: false}"></div>
上記の例では、div
要素にred
ではなくgreen
のclassが追加される。
比較演算子と論理演算子も使用できる。
次が使用例。
<div :class="{green: 5 > 1, red: false && 9 < 16}"></div>
v-model
- 双方向データバインディング(Two-way data binding)
v-model
ディレクティブを使うと、双方向のデータバインディングを実現できる。つまり、ユーザーはinput
を使用してデータを変更し、必要に応じて結果を同時に確認できる。
<input v-model="message" placeholder="メッセージを入力">
<p>メッセージ: {{ message }}</p>
let app = new Vue({
el: '#app',
data: {
message: ''
}
});
このv-model
ディレクティブは、ほとんどすべてのinput
タイプで機能する。
v-on
- イベント(Event)
イベントは、要素に対して特定のアクションが実行されたときに呼び出される。
イベントはv-on
ディレクティブを使って宣言する。
<div id="app">
<button v-on:click="callMyfunction"></button>
</div>
let app = new Vue({
el: '#app',
methods: {
callMyfunction() {
alert('This is it!');
}
}
});
このボタンをクリックすると、callMyFunction
メソッドが呼び出される。
匿名関数も使うことができる。
<button v-on:click="() => alert('こんにちは!')"></button>
v-on
の省略形には@
を使う。
<button @click="() => alert('こんにちは!')"></button>
[ ]
- 動的引数(Dynamic arguments)
属性名を評価させたい場合3はどうするか。これは次のようにすることで可能。
<div v-bind:[myAttribute]="myData"></div>
イベント名を動的にアタッチすることもできる。
<div v-on:[myEvent]="doSomething"></div>
オブジェクトによる動的引数
次のように、オブジェクトとJavaScriptのネイティブ動的キー構文を使用して動的引数をバインドする方法もある。
<button v-on="{[myAttr]: true}">可能な場合はクリック</button>
let app = new Vue({
el: '#app',
data: {
myAttr: 'disabled'
}
});
これはイベントにも使用可能。
<button v-on="{[myEvent]: function() { alert("Hello world!") }}">こんにちは!</button>
let app = new Vue({
el: '#app',
data: {
myEvent: 'click'
}
});
computed
- 算出プロパティ(Computed property)
算出プロパティ(computed
)はコードを簡潔にする方法の1つ。算出プロパティはMustashe構文内などでJavaScript式の代わりに使うことができる。
次のコードがあるとする。
<p>
ベストなプログラミング言語:{{ programmingLanguages }}<br>
ワーストなプログラミング言語:{{ programmingLanguages.split(', ').reverse().join(', ') }}
</p>
代わりに、次のような算出プロパティを定義して、worstProgrammingLanguages
の代わりに使用できる。
<p>
ベストなプログラミング言語: {{ programmingLanguages }}<br>
ワーストなプログラミング言語: {{ worstProgrammingLanguages }}
</p>
// ※言語の順位というのはは本当ではなくただの例えです
let app = new Vue({
el: '#app',
data: {
programmingLangauges: 'JavaScript, C#, PHP, Python, LALALA, HOHOHO'
},
computed: {
worstProgrammingLanguages() {
return this.programmingLangauges.split(', ').reverse().join(', ');
}
}
});
算出プロパティはゲッターとして機能する。つまり、何かを返すだけで、データをセットする役割はない。
が次のようにこの動作を変更して、データに対するset
メソッドとget
メソッドの両方を設定できる。
let app = new Vue({
el: '#app',
data: {
myFirstName: 'Masa',
myLastName: 'U'
},
computed: {
myFullName: {
get(): {
return this.myFirstName + ' ' + this.myLastName;
},
set(v): {
let parts = v.split(' ');
this.myFirstName = parts[0];
this.myLastName = parts[1];
}
}
}
});
上記のコードは、文字列をスペースで分割し、データを設定しようとしているときに最初の部分をファーストネームとして、2番目の部分をラストネームとしてセットする。myFullName
が、データを取得するときは名と姓が連結されている。
watch
- ウォッチャ(Watcher)
データがいつ変更されたかを知るためには一般的にウォッチャ(watch
オプションで設定)を使う。
let app = new Vue({
el: '#app',
data: {
myAge: 19
},
// 設定されたプロパティ(監視プロパティ)をモニタリングして、変化があったときに働く
watch: {
myAge: function myAge(v) {
console.log('私は' + v + '歳です。');
}
}
});
注意:ウォッチャは、データ自体を操作しない(データの変化をモニタリングする)。
v-if
- 条件付きレンダリング
条件付きレンダリングは、いくつかの条件に従ってUIの一部を表示させたいときに使われる。これにはv-if/v-else
を使う。
<!-- isUserLoggedInの戻り値がtrueの時はHello userが表示される -->
<span v-if="isUserLoggedIn">Hello user</span>
<span v-else>Hi guest!</span>
条件にはv-else-if
も含めることができる。
<!-- 条件式の評価値によって表示される要素が変わる -->
<span v-if="favoriteColor === '赤'">赤い林檎</span>
<span v-else-if="favoriteColor === '青'">青い空</span>
<span v-else>うーん...</span>
Vueはスマートで、異なるパーツのみを取り換える。
たとえば、Eメール、あるいはユーザー名でログインするための入力がある場合、条件によって2つの部分を切り替えてもinput
要素を消去して再レンダリングしないため、ユーザーの入力値は削除されないままとなる。
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
ただし、key
を使用することで、これらのフィールドが完全に異なり再レンダリングする必要があることをVueインスタンスに伝えることが可能になる。
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
v-show
- 条件付き表示切替
v-show
を使って要素をレンダリングはするが非表示にすることができる(v-show=false
の時はdisplay
プロパティをnone
にセットして非表示にしている)。
<span v-show="true">やあ!</span>
注意:v-showは<template>
要素に対しては使えない。v-else
と一緒に使うこともできない。
注意:v-if
は遅延描画である。つまり、最初にfalse状態のブロックはレンダリングされない。一方、v-show
は実際にはレンダリングしているが、レンダリングされたブロックは非表示なっている。
v-for
- リストレンダリング(List rendering)
一連のデータのレンダリングは、他のプログラミング言語でのループに相当する。
これにはv-for
ディレクティブを使う。
配列に対して
多くの場合、配列を反復処理してレンダリングしたい場合がある。
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Hoge' },
{ message: 'Fuga' }
]
}
});
第2引数を渡して、現在のアイテムのインデックスにアクセスできる。
<ul id="example-2">
<li v-for="(item, index) in items">
{{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
items: [
{ message: 'Hoge' },
{ message: 'Fuga' }
]
}
});
オブジェクトに対して
オブジェクトのレンダリングは、配列のレンダリングよりも単純。
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
});
第2引数を使用して、プロパティの名前にアクセスすることもできる。
<ul id="v-for-object" class="demo">
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
});
オブジェクトを反復処理するときに、インデックスへのアクセスも利用できる。
<ul id="v-for-object" class="demo">
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
});
範囲に対して
数字の範囲を反復処理するのもとても簡単にできる。
<div>
<span v-for="n in 10">{{ n }} </span>
</div>