VueCONF 2019 에서 Chris Fritz (Vue.js 핵심 팀 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가 계산 된 값을 component에서 parent로 전달하십시오 .
이제 다음과 같이 부모 구성 요소에서 생성 된이 사용자 지정 이벤트를 수신하면됩니다.
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는 다양한 방식으로 우리의 삶을 훨씬 쉽게 만들어 줄 것입니다. 이에 대한 예제 중 하나는을 사용하여 구성이 훨씬 적은 더 간단한 투명 래퍼 를 만드는 데 도움이된다는 것입니다 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"