これからはじめるVue.js実践入門
posted with ヨメレバ
山田 祥寛 SBクリエイティブ 2019年08月23日頃
コンポーネント(応用)
<component>要素
- コンポーネントの入れ物であり、コンポーネントを動的に切り替えることができる。
- タブで表示内容を切り替える場合などに便利。
定義
components: {
'my-component1': { template: `<p>my-component1</p>`, },
'my-component2': { template: `<p>my-component2</p>`, },
},
data: { index: 1, },
created: function() {
this.interval = setInterval(() => {
this.index = (this.index % 2) + 1
}, 1000)
},
beforeDestroy: function() { clearInterval(this.interval); }
呼び出し
<component v-bind:is="`my-component${index}`"></component>
使い方
- 表示するコンポーネント名を
v-bind:is="xxx"
で指定する。 - input要素などがある場合、入力内容はコンポーネント切り替え時に破棄されてしまう。
- <component>要素を<keep-aliove>で囲むと、コンポーネントがキャッシュされ入力内容が消えなくなる。
<keep-aliove>要素は、max属性でキャッシュの最大数、include, exclude属性でキャッシュするしないをコンポーネント名で指定することができる。
自作のコンポーネントでのv-modelの利用
- コンポーネント間のデータ交換は、プロパティと$emitを使うのが基本だが、v-modelを自作のコンポーネントで利用することもできる。
- ただし、コンポーネントにvalueプロパティを用意し、それを配下のinput要素などにバインドし、inputイベントを$emitしなければならない。
定義
'my-input': {
template: `<p><input type="text" v-bind:value="value" v-on:input="$emit('input', $event.target.value)"></p>`,
props: ['value'],
},
呼び出し
<my-input v-model="msg"></my-input>{{ msg }}
これは <my-input v-bind:value="msg" v-on:input="msg=$event"></my-input>{{ msg }}
と同じ意味である。
input以外のイベントを使う場合
- デフォルトではv-modelはvalueプロパティとinputイベントに紐づく。
- 変更したい場合は、modelオプションでpropとeventを指定する。
'my-input': {
template: `<p><input type="text" v-bind:value="name" v-on:input="$emit('change', $event.target.value)"></p>`,
props: ['name'],
model: {
prop: 'name',
event: 'change'
}
},
.syncs修飾子による複数プロパティの双方向バインディング
- v-bindの.sync修飾子はv-modelと同じ機能を提供する。
- v-modelと.sync修飾子は同じ役割を持つが、単一の場合はv-modelを使えばよい。
双方向バインディングが必要なプロパティが複数ある場合のみ.sync修飾子を使う。
定義
'my-input': {
template: `<p><input type="text" v-bind:value="text1" v-on:input="$emit('update:text1', $event.target.value)"></p>`,
props: ['text1'],
},
呼び出し
<my-input v-bind:text1.sync="msg"></my-input>{{ msg }}
使い方
- propsにxxxを定義し、
v-bind:value="xxx" v-on:input="$emit('update:xxx', $event.target.value)"
とする。 v-bind:xxx.sync="yyy"
で呼び出す。
アニメーション
<transition></transition>の直下の要素(単一でなければならない)は、描画切り替え(v-if, f-show)のタイミングでアニメーション用のクラスが付与される。]
- アニメーション前:.v-enter, v-leave
- アニメーション後:.v-enter-to, .v-leave-to
- 変化の度合いや時間の指定:.v-enter-active, .v-leave-active
- 他にもリストの追加・削除・ソート時のアニメーションも可能だが、ここでは省略する。
<transition>
<div class="panel" v-show="flag">アニメーションテスト</div>
</transition>
<p><button v-on:click="flag=!flag">表示/非表示</button></p>
<style>
.panel {
width: 300px;
height: 200px;
border: solid 1px #000;
background-color: #00b8d4;
}
.v-enter,
.v-leave-to {
height: 0px;
}
.v-enter-to,
.v-leave {
height: 200px;
}
.v-enter-active,
.v-leave-active {
transition: height 3s;
}
</style>
Element
Vue.jsで利用できるコンポーネントライブラリ。
<!-- 読み込み -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/element-ui@2.14.0/lib/umd/locale/ja.js"></script>
<!-- Button -->
<button type="button" class="el-button el-button--primary">Primary</button>
<!-- Transfer -->
<el-transfer v-model="transferValue" :data="transferData" v-bind:titles="['選択元', '選択先']"></el-transfer>
<script>
ELEMENT.locale(ELEMENT.lang.ja);
const app = new Vue({
el: '#app',
data: {
transferValue: [],
transferData: [{key: 1, label: 'りんご'}, {key: 2, label: 'みかん'}, {key: 3, label: 'ぶどう'}]
},
})
</script>
ミックスイン
- 複数のコンポーネントで同一のコードが存在する場合、ミックスインとして共通コードを抜き出すことでコンポーネントに動的に適用できるようになる。
- ミックスインはオブジェクトリテラルであり、data, methods, computed,ライフサイクルフックなどコンポーネントで利用できる全てのオプションを利用できる。
- ミックスインの名前は〜ableとすると内容がわかりやすくなる。
定義
const mixinTest = {
mounted() {
console.log(this.$data);
},
}
コンポーネントへの適用
- mixinsオプションに配列で指定する。
- コンポーネントとミックスインでオプションが競合した場合
- data, methods, computedなどはマージされる。
- dataに同じキー名が存在する場合はコンポーネント側が優先される。
- ライフサイクルフックは、ミックスイン⇒コンポーネントの順番で実行される。
- グローバルミックスイン Vue.mixin()で全てのコンポーネントに適用させるグローバルミックスインを定義することもできるが、アプリ全体に影響が及ぶためあまり使用するべきではない。
<script>
new Vue({
el: '#app',
components: {
'my-mixin': {
template: `<p>my-mixin</p>`,
data() {
return {
hoge: 'hoge',
}
},
mixins: [mixinTest],
},
}
});
</script>