Vue.js组件向主Vue实例触发点击事件失败的问题排查
解决Vue组件向主实例触发自定义事件失败的问题
我帮你梳理下代码里的问题点,一步步搞定这个事件触发的问题:
问题根源拆解
你的代码里有几个关键错误导致事件没成功触发:
- 主实例方法位置错误:你把
toggleLeftUserPanel直接写在了Vue实例的根属性里,但Vue要求实例方法必须放在methods对象内部,否则无法被识别。 - 组件未绑定监听事件:组件内部用
$emit抛出了toggleLeftUserPanel事件,但在使用<left-user-list-tile>组件时,没有在标签上绑定这个事件的监听逻辑,相当于事件抛出去但没人接。 - 组件内冗余方法:你在组件的
methods里定义了toggleLeftUserPanel,但模板里已经直接通过@click="$emit(...)"触发事件了,这个方法完全没必要保留。 - 变量赋值错误:主实例里的
this.leftUserPanel != this.leftUserPanel只是做了一次比较,并没有真正修改变量值,应该用this.leftUserPanel = !this.leftUserPanel来完成取反操作。 - 根实例props冗余:根Vue实例不需要
props选项,这个是给子组件接收父组件数据用的,根实例可以直接去掉这个配置。
修正后的完整代码
组件文件 LeftUserListTileComponent.vue
<template> <v-list-tile @click="$emit('toggle-left-user-panel')"> <v-list-tile-action> <v-icon>exit_to_app</v-icon> </v-list-tile-action> <v-list-tile-content> <v-list-tile-title>User Settings</v-list-tile-title> </v-list-tile-content> </v-list-tile> </template> <script> export default { data () { return { } } // 移除了多余的toggleLeftUserPanel方法 } </script>
主实例代码
Vue.component('left-user-list-tile', require('./components/LeftUserListTileComponent.vue')); Vue.component('left-user-panel', require('./components/LeftUserPanelComponent.vue')); const app = new Vue({ el: '#app', data: { leftUserPanel: false // 给个明确的初始值,比null更合理 }, methods: { // 所有方法必须放在这个对象里 toggleLeftUserPanel () { console.log("In toggleLeftUserPanel func"); this.leftUserPanel = !this.leftUserPanel; // 正确的取反赋值逻辑 } } });
根模板的组件使用(关键:绑定事件)
在你的#app根模板里,使用组件时要绑定自定义事件:
<div id="app"> <!-- 用短横线分隔的事件名绑定主实例的方法 --> <left-user-list-tile @toggle-left-user-panel="toggleLeftUserPanel"></left-user-list-tile> <!-- 可以根据leftUserPanel的值控制面板显示 --> <left-user-panel v-show="leftUserPanel"></left-user-panel> </div>
额外说明
- Vue自定义事件在模板中推荐用短横线分隔命名(比如把
toggleLeftUserPanel转为toggle-left-user-panel),这更符合HTML属性的命名习惯,当然Vue2也支持直接用驼峰,但短横线写法更规范。 - 组件通过
$emit抛出事件后,必须在父级(这里是根实例)的组件标签上用@事件名监听,才能触发对应的处理方法。
内容的提问来源于stack exchange,提问作者tigerel
相关产品推荐
相关产品推荐

