Vue.js コンポーネント - カスタム イベント
親コンポーネントは props を使用して子コンポーネントにデータを渡しますが、子コンポーネントがデータを返したい場合は、カスタム イベントを使用する必要があります。
v-on を使用してカスタム イベントをバインドでき、各 Vue インスタンスはイベント インターフェイス (Events インターフェイス) を実装します。つまり、次のようになります。
$on(eventName)
リスナーイベントを使用する$emit(eventName)
トリガーイベントの使用
さらに、親コンポーネントは v-on を直接使用して、子コンポーネントが使用されている子コンポーネントによってトリガーされたイベントをリッスンすることができます。
次の例では、子コンポーネントがその外部から完全に切り離されています。親コンポーネントが処理する内部イベントをトリガーするだけです。
例
<div id="app">
<div id="counter-event-example">
<p>{
{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</div>
<script>
Vue.component('button-counter', {
template: '<button v-on:click="incrementHandler">{
{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
</script>
コンポーネントのルート要素でネイティブ イベントをリッスンする場合。.native を使用して v-on を変更できます。例えば:
<my-component v-on:click.native="doTheThing"></my-component>
データは関数でなければなりません
上の例では、ボタンカウンターコンポーネントのデータがオブジェクトではなく関数であることがわかります。
data: function () {
return {
count: 0
}
}
この利点は、各インスタンスが返されたオブジェクトの独立したコピーを維持できることです。データがオブジェクトの場合、次のように他のインスタンスに影響を与えます。
例
<div id="components-demo3" class="demo">
<button-counter2></button-counter2>
<button-counter2></button-counter2>
<button-counter2></button-counter2>
</div>
<script>
var buttonCounter2Data = {
count: 0
}
Vue.component('button-counter2', {
/*
data: function () {
// data 选项是一个函数,组件不相互影响
return {
count: 0
}
},
*/
data: function () {
// data 选项是一个对象,会影响到其他实例
return buttonCounter2Data
},
template: '<button v-on:click="count++">点击了 {
{ count }} 次。</button>'
})
new Vue({ el: '#components-demo3' })
</script>
カスタムコンポーネントのv-model
コンポーネントの v-model は、デフォルトで value という名前のプロップと input という名前のイベントを利用します。
<input v-model="parentData">
に相当:
<input
:value="parentData"
@input="parentData = $event.target.value"
>
次の例では、コンポーネント kxdang-input をカスタマイズします。親コンポーネントの数値の初期値は 100 です。子コンポーネントの値を変更すると、親コンポーネントの数値をリアルタイムで更新できます。
例
<div id="app">
<kxdang-input v-model="num"></kxdang-input>
<p>输入的数字为:{
{num}}</p>
</div>
<script>
Vue.component('kxdang-input', {
template: `
<p> <!-- 包含了名为 input 的事件 -->
<input
ref="input"
:value="value"
@input="$emit('input', $event.target.value)"
>
</p>
`,
props: ['value'], // 名为 value 的 prop
})
new Vue({
el: '#app',
data: {
num: 100,
}
})
</script>
v-model はチェックされずにデフォルトで値を渡すため、現在のイベント タイプと受信プロパティを指定できるチェック ボックスまたはラジオ ボックス コンポーネントのモデル オプションを使用する必要があります。
例
<div id="app">
<base-checkbox v-model="lovingVue"></base-checkbox>
<div v-show="lovingVue">
如果选择框打勾我就会显示。
</div>
</div>
<script>
// 注册
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change' // onchange 事件
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
// 创建根实例
new Vue({
el: '#app',
data: {
lovingVue: true
}
})
</script>
インスタンス内のlavingVueの値はチェックされたプロパティに渡され、<base-checkbox>によって変更イベントがトリガーされると、loveVueの値も更新されます。