我正在将我的中型应用程序从Vue2迁移到Vue3。我注意到Vue3的子-父发射机制与Vue2不同,这让我很困惑。
下面是一个基本示例
// App.vue
<script>
import InputWrap from './InputWrap.vue';
export default {
name: 'App',
components: {
InputWrap,
},
data() {
return {
msg: 'Hello world',
}
},
methods: {
onChange() {
console.log('why change?');
}
}
}
</script>
<template>
<h1>{{ msg }}</h1>
<input-wrap v-model="msg" @change="onChange" />
</template>
// InputWrap.vue
<script>
import MyInput from './MyInput.vue';
export default {
name: 'InputWrap',
components: {
MyInput,
},
props: ['modelValue'],
methods: {
onUpdate(v) {
this.$emit('update:modelValue', v);
}
}
}
</script>
<template>
<my-input :modelValue="modelValue" @update:modelValue="onUpdate" />
</template>
// MyInput.vue
<script>
export default {
name: 'MyInput',
props: {
modelValue: String,
},
methods: {
onInput(e) {
this.$emit('update:modelValue', e.target.value);
}
}
}
</script>
<template>
<input :value="modelValue" @input="onInput" />
</template>
连接到Vue SFCPlayground。
我很好奇为什么onChange
事件处理程序在App.vue
中被调用?
看起来change
事件是由MyInput.vue
中的input元素生成的。但是为什么这个事件会通过所有组件并在App.vue
中被捕获,这一点完全不透明。想象一下,一棵树有几十个嵌套的组件,一个根组件在侦听change
事件。这完全是一团糟。
Vue2有一个不同的方法,我喜欢它,因为它有一个透明的子-父通信。有可能打开Vue2发射机制在Vue3?
1条答案
按热度按时间l0oc07j21#
原因是Vue实现了故障属性机制
“fallthrough属性”是传递给组件的属性或
v-on
事件侦听器,但未在接收组件的props或emits中显式声明。当组件呈现单个根元素时,fallthrough属性将自动添加到根元素的属性
在示例中,零部件满足两个条件:
InputWrap.vue
渲染单个根元素(MyInput.vue
组件)InputWrap.vue
不将onChange
声明为组件的发射与
MyInput.vue
组件相同因此
@change
侦听器将无法到达input元素。要禁用fallthrough属性,您可以将属性声明为子组件的
props/emits
,或者通过添加inheritAttrs: false
禁用该组件的整个功能:SFC链路
Vue 2仅继承属性