Vue.js 中級編
おさらい
算出プロパティ
new Vue({
el: '#app',
data: {
text: 'Vue.js is awesome'
},
computed: {
upperText() {
return this.text.toUpperCase()
}
}
})
<div id="#app">
{{ upperText }}
</div>
プロパティとして
アクセスする
算出プロパティ | メソッド | |
---|---|---|
オプション名 | computed | methods |
呼び出し方 | プロパティ {{ someProp }} |
メソッド {{ someMethod() }} |
キャッシュ | される | されない |
引数 | なし | あり |
注意点
Date.now() など Vue.js 以外で値が変わるものを
算出プロパティの中で使うとうまく更新が反映されない
https://codepen.io/ktsn/pen/OoywbP?editors=1111
ウォッチャー
new Vue({
el: '#app',
data: {
text: 'hello'
},
watch: {
text(newValue, oldValue) {
// this.text が変わったときに実行される
}
}
})
new Vue({
// ...
watch: {
text: {
handler(newValue, oldValue) {
// this.text が変わったときに実行される
},
immediate: true, // 初期値設定時にも実行されるようにする
deep: true // オブジェクトの子孫も監視する
}
}
})
watch のオプション
// 文字列
vm.$watch('a.b.c', function (newVal, oldVal) {
// vm.a.b.c が変更されたら実行される
})
// 関数
vm.$watch(
function () {
return this.a + this.b
},
function (newVal, oldVal) {
// this.a + this.b の値が変わったら実行される
}
)
ライフサイクル
例えば……
- created でスライダーのページめくりのタイマーを起動
- mounted で外部の UI ライブラリをマウント
- beforeDestroy で↑のような処理を無効化
コンポーネント
Vue.component('v-button', {
template: `...`,
props: { /* ... */ },
// ... インスタンスオプションと同様 ...
}
グローバルに登録
すべてのテンプレートで使えるようにする
const VButton = {
template: `...`,
props: { /* ... */ },
// ... インスタンスオプションと同様 ...
}
// 他のコンポーネント
const AnotherComp = {
// VButton を登録
components: { VButton }
}
ローカルに登録
あるコンポーネントのテンプレートでのみ使えるようにする
Vue.component('v-button', {
props: {
// theme プロパティを定義
// `this.theme` で参照できる
theme: {
type: String,
default: null
}
},
// ... インスタンスオプションと同様 ...
})
props
コンポーネントにデータを渡す
<!-- theme に 'blue' を渡す -->
<v-button theme="blue" />
Vue.component('v-button', {
methods: {
onClick () {
// `click` イベントを送出
this.$emit('click')
}
}
// ... インスタンスオプションと同様 ...
})
カスタムイベント
コンポーネントの外側にイベントを通知
<!-- クリックを監視 -->
<v-button
v-on:click="onClickButton"
/>
Vue.component('v-button', {
// 一部省略
template: `<button>
<span>
<slot />
</span>
</button>`
// ... インスタンスオプションと同様 ...
})
スロット
コンポーネントの小要素を指定の場所に配置
<!-- 小要素が slot と差し替わる -->
<v-button>
ボタンテキスト
</v-button>
Vue.component('v-button', {
// 初期データを返す関数
data() {
return {
localData: 'hoge'
}
}
})
data の書き方の違い
初期データを返す関数にする必要がある
単一ファイル
コンポーネント
<template>
<!-- コンポーネントのテンプレート -->
</template>
<script>
// コンポーネントオプション
export default {
data () { /* ... */ }
}
</script>
<style>
/* コンポーネントのスタイル */
</style>
<template lang="pug">
//- Pug
button.button(type="button")
slot
</template>
<script lang="ts">
// TypeScript
import Vue from 'vue'
export default Vue.extend({
data () { /* ... */ }
})
</script>
<style lang="scss">
/* SCSS */
.button {
&_text {
}
}
</style>
Scoped CSS
scoped とつけるとスタイルがコンポーネント外に漏れなくなる
<template>
<button class="button">
<slot />
</button>
</template>
<style scoped>
/* このコンポーネントにのみ適用 */
.button {
background-color: blue;
}
</style>
応用
既存ライブラリをコンポーネントにする
Further Reading
- Vue.js 公式ガイド
https://jp.vuejs.org/v2/guide/
- Vue.js 公式クックブック
https://jp.vuejs.org/v2/cookbook/
- やわらかVue.js
https://scrapbox.io/vue-yawaraka/
- Vue.js入門 (技評の Web 連載)
https://gihyo.jp/dev/serial/01/vuejs
- Vue.js入門 基礎から実践アプリケーション開発まで
9月22日発売
Vue.js 中級編
By katashin
Vue.js 中級編
- 2,743