VueCONF US 2019の Chris Fritz(Vue.js Core Team Emeriti)が述べたように
Kiaを.native
入力してから、ベース入力のルート要素が入力からラベルに変更された場合、このコンポーネントは突然壊れ、それは明白ではありません。実際、本当に良いテストがない限り、すぐにキャッチすることすらできません。代わりに、現在アンチパターンがVue 3で削除されると私が考えている.native
修飾子の使用を回避することにより、親がどの要素リスナーが追加されるかを気にするかもしれないことを明示的に定義することができます...
Vue 2を使用
使用$listeners
:
したがって、Vue 2を使用している場合、この問題を解決するには、完全に透過的なラッパーロジックを使用することをお勧めします。このため、Vueは$listeners
コンポーネントで使用されているリスナーのオブジェクトを含むプロパティを提供します。例えば:
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
その後、次のようにコンポーネントに追加v-on="$listeners"
する必要がありtest
ます。
Test.vue(子コンポーネント)
<template>
<div v-on="$listeners">
click here
</div>
</template>
これで<test>
コンポーネントは完全に透明なラッパーになりました。つまり、通常の<div>
要素とまったく同じように使用できます。すべてのリスナーは.native
修飾子なしで機能します。
デモ:
Vue.component('test', {
template: `
<div class="child" v-on="$listeners">
Click here
</div>`
})
new Vue({
el: "#myApp",
data: {},
methods: {
testFunction: function(event) {
console.log('test clicked')
}
}
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @click="testFunction"></test>
</div>
$emit
この目的でメソッドを使用することもできます。これは、親コンポーネントの子コンポーネントイベントをリッスンするのに役立ちます。このため、最初に次のように子コンポーネントからカスタムイベントを発行する必要があります。
Test.vue(子コンポーネント)
<test @click="$emit('my-event')"></test>
重要:イベント名には常にケバブケースを使用してください。この点に関する詳細とデモについては、この回答を確認してください:VueJSが計算された値をコンポーネントから親に渡します。
ここで、次のように、親コンポーネントでこの発行されたカスタムイベントをリッスンする必要があります。
App.vue
<test @my-event="testFunction"></test>
だから、基本的には代わりのv-on:click
か、速記@click
、我々は単に使用するv-on:my-event
か、単に@my-event
。
デモ:
Vue.component('test', {
template: `
<div class="child" @click="$emit('my-event')">
Click here
</div>`
})
new Vue({
el: "#myApp",
data: {},
methods: {
testFunction: function(event) {
console.log('test clicked')
}
}
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @my-event="testFunction"></test>
</div>
Vue 3を使用
使用v-bind="$attrs"
:
Vue 3は、多くの点で私たちの生活をはるかに簡単にします。その例の1つは、を使用するだけで、非常に少ない構成でシンプルな透過ラッパーを作成するのに役立つことv-bind="$attrs"
です。これを子コンポーネントで使用すると、リスナーが親から直接機能するだけでなく、他の属性も通常と同じように機能します<div>
。
したがって、この質問に関しては、Vue 3で何も更新する必要はありません。<div>
ここでのルート要素と同様に、コードは引き続き正常に機能し、すべての子イベントを自動的にリッスンします。
デモ#1:
const { createApp } = Vue;
const Test = {
template: `
<div class="child">
Click here
</div>`
};
const App = {
components: { Test },
setup() {
const testFunction = event => {
console.log("test clicked");
};
return { testFunction };
}
};
createApp(App).mount("#myApp");
div.child{border:5px dotted orange; padding:20px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
<test v-on:click="testFunction"></test>
</div>
しかし<input />
、親ラベルの代わりに属性とイベントをメインに適用する必要があるネストされた要素を持つ複雑なコンポーネントの場合、単純に次のように使用できますv-bind="$attrs"
デモ#2:
const { createApp } = Vue;
const BaseInput = {
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input v-bind="$attrs">
</label>`
};
const App = {
components: { BaseInput },
setup() {
const search = event => {
console.clear();
console.log("Searching...", event.target.value);
};
return { search };
}
};
createApp(App).mount("#myApp");
input{padding:8px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
<base-input
label="Search: "
placeholder="Search"
@keyup="search">
</base-input><br/>
</div>
@click.native="testFunction"