これからはじめる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> 
  
  
  
  
コメント