Vue3中使用mitt事件总线结合下拉框出现TypeError问题求助
解决Vue中Mitt事件总线触发时的TypeError问题
问题场景
已在main.js中配置Mitt作为全局事件总线:
import { createApp } from "vue"; import App from './App.vue' import mitt from "mitt"; const emitter = mitt(); const app = createApp(App); app.config.globalProperties.emitter = emitter; app.mount("#app");
子组件ComboBox通过事件总线发布事件:
<template> <div class= "combobox"> <!-- 注意:原for属性写法错误,需改为Vue绑定语法 --> <label :for="selector_name"> <p>{{ selector_title }}</p> </label> <select :name="selector_name" :id="selector_id" :disabled="disabled" @change="onChange"> <option v-for="(opt, index) in selector_options" :key="`opt ${index}`"> {{ opt }} </option> </select> </div> </template> <script> export default { name: 'ComboBox', data() { return { disabled: false, }; }, props: { selector_title: { type: String, required: true }, selector_name: { type: String, required: true }, selector_id: { type: String, default: "combobox" }, selector_options: { type: Array, required: true }, }, methods: { onChange(event){ this.emitter.emit('lock-combobox', { id: this.selector_id }); }, }, } </script>
父组件Controls订阅事件,但触发下拉框选项时抛出Uncaught TypeError: undefined has no properties错误:
<template> <div id="controls" class="param"> <div class="control" id="combobox1"> <ComboBox selector_title = "Pattern" selector_name = "pattern" :selector_options="['complex', 'simple']" selector_id="combo1" ref="combo1" /> </div> <div class="control" id="combobox2"> <ComboBox selector_title = "Hand" selector_name = "pattern" :selector_options="['Left', 'Right']" selector_id="combo2" ref="combo2" /> </div> <div class="control" id="speedslider"> <SpeedSlider/> </div> <div class="control" id="startstop"> <StartStopButton/> </div> <div class="control" id="emergency"> <Emergency/> </div> </div> </template> <script> import ComboBox from '../components/ComboBox.vue'; export default { name: "Controls", components: { ComboBox, }, created() { this.emitter.on('lock-combobox', (event) => { // 原写法逻辑错误,导致undefined访问 this.$refs.event.id.disabled = true; }); }, } </script>
错误原因
- 父组件事件回调中错误使用
this.$refs.event.id:event是我们传递的自定义参数对象,并非$refs中的组件引用名称,因此this.$refs.event返回undefined,访问其属性触发TypeError。 - 直接操作DOM的
disabled属性不符合Vue数据驱动的设计,应通过修改子组件的响应式数据控制状态。
修复方案
修改父组件的事件回调逻辑,通过传递的id匹配对应的子组件引用,再修改子组件的响应式数据:
<script> import ComboBox from '../components/ComboBox.vue'; export default { name: "Controls", components: { ComboBox, }, created() { this.emitter.on('lock-combobox', (payload) => { // 通过payload.id获取目标子组件的ref const targetCombo = this.$refs[payload.id]; if (targetCombo) { // 修改子组件的disabled响应式状态 targetCombo.disabled = true; } }); }, } </script>
同时修正子组件中label的for属性绑定方式,原写法for={{selector_name}}存在语法错误,需改为:for="selector_name"以符合Vue的属性绑定规则。
内容的提问来源于stack exchange,提问作者Bilal
相关产品推荐
相关产品推荐

