在 Vue.js 中,自定义事件可以用于父组件和子组件之间传递数据,与 props 相比,自定义事件传递数据的优势是可以进行事件的解绑,也就是可以做到动态地传递数据,开发起来更加灵活。
自定义事件的步骤如下:
(1)在父组件中绑定自定义事件
方法1:
<!-- 绑定 baciii 事件 --> <Student @baciii="demo" /> <Student v-on:baciii="demo" />
方法2:
// 绑定 baciii 事件 this.$refs.student.$on('baciii', this.demo);
(2)在子组件中执行自定义事件
<div id="app"> <button @click="sendstudentname"> </div> <script type="text/javascript"> var app = new Vue({ el: "#app", data: {}, methods: { sendstudentname: function() { // 触发自定义事件 this.$emit('baciii', this.name); } } }); </script>
在子组件中解绑事件:
// 方法1:解绑一个事件 this.$off('baciii'); // 方法2:解绑多个事件用数组 this.$off(['baciii','demo1']); // 方法3:解绑所有自定义事件 this.$off();
注意,自定义事件名不同于组件和 props,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 camelCase 名字的事件:
this.$emit('myEvent')
则监听这个名字的 kebab-case 版本是不会有任何效果的:
<!-- 没有效果 --> <my-component v-on:my-event="doSomething"></my-component>
不同于组件和 props,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent —— 导致 myEvent 不可能被监听到。
因此,我们推荐你始终使用 kebab-case 的事件名,如 v-on:my-event。
<html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue</title> <!-- 使用 CDN 引入 Vue 库 --> <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> --> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.9/vue.js"></script> </head> <body> <div id="app"> <h1>{{ data || "-" }}</h1> <!-- 绑定 send_data 自定义事件 --> <my-component v-on:send_data="setData"></my-component> </div> <script type="text/javascript"> Vue.component('my-component', { data: function(){ return { data: "" }; }, template: ` <div> <input type="text" placeholder="Enter data" v-model="data" /> <p> <button v-on:click="sendData">Send Data</button> </p> </div> `, methods: { sendData: function() { // 触发自定义事件 send_data,并且将 data 当做数据传递给自定义事件 this.$emit('send_data', this.data); } } }); var app = new Vue({ el: "#app", data: { data: null }, methods: { // 接收子组件传递过来的数据,data 为子组件传递的数据 setData: function(data) { this.data = data; } } }); </script> </body> </html>
运行效果如下: