Vue 3.0 自定义事件
#事件名不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 camelCase 名字的事件:
this.$emit('myEvent')
则监听这个名字的 kebab-case 版本是不会有任何效果的:
<!-- 没有效果 -->
<my-component @my-event="doSomething"></my-component>
不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 @myEvent 将会变成 @myevent——导致 myEvent 不可能被监听到。
因此,我们推荐你始终使用 kebab-case 的事件名。
#定义自定义事件
在 Vue School 上观看关于定义自定义事件的免费视频。
可以通过 emits 选项在组件上定义已发出的事件。
app.component('custom-form', {
emits: ['in-focus', 'submit']
})
当在 emits 选项中定义了原生事件 (如 click) 时,将使用组件中的事件替代原生事件侦听器。
TIP
建议定义所有发出的事件,以便更好地记录组件应该如何工作。
#验证抛出的事件
与 prop 类型验证类似,如果使用对象语法而不是数组语法定义发出的事件,则可以验证它。
要添加验证,将为事件分配一个函数,该函数接收传递给 $emit 调用的参数,并返回一个布尔值以指示事件是否有效。
app.component('custom-form', {
emits: {
// 没有验证
click: null,
// 验证submit 事件
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Invalid submit event payload!')
return false
}
}
},
methods: {
submitForm() {
this.$emit('submit', { email, password })
}
}
})
#v-model 参数
默认情况下,组件上的 v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件。我们可以通过向 v-model 传递参数来修改这些名称:
<my-component v-model:foo="bar"></my-component>
在本例中,子组件将需要一个 foo prop 并发出 update:foo 要同步的事件:
const app = Vue.createApp({})
app.component('my-component', {
props: {
foo: String
},
template: `
<input
type="text"
:value="foo"
@input="$emit('update:foo', $event.target.value)">
`
})
<my-component v-model:foo="bar"></my-component>
#多个 v-model 绑定
通过利用以特定 prop 和事件为目标的能力,正如我们之前在 v-model 参数中所学的那样,我们现在可以在单个组件实例上创建多个 v-model 绑定。
每个 v-model 将同步到不同的 prop,而不需要在组件中添加额外的选项:
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
const app = Vue.createApp({})
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
template: `
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)">
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)">
`
})
点击此处实现
页:
[1]