Vue中如何为动态挂载的自定义组件设置绑定的事件属性
修复方案
你的代码存在3个核心逻辑错误,按以下步骤调整即可:
- 错误1:混淆了props传参和事件绑定逻辑。
propsData仅用于向组件传递props值,自定义事件不能写在propsData里,Vue2中动态创建的组件实例需要通过$on方法绑定事件监听。 - 错误2:子组件中
$emit用法错误。$emit的作用是向父组件派发事件通知,无法直接获取父组件的返回值,你需要的鉴权状态应该通过props由父组件传入,而不是靠emit触发获取。 - 错误3:props中传入的方法提前执行。你在
propsData里写的this.isUserAuthenticated()?this.signOut():this.signInUser()会在组件初始化时直接执行,不会等到事件触发时运行。
第一步:修正子组件代码
把需要父组件传入的参数明确定义为props,事件仅用于派发点击通知,不要通过emit拿返回值:
<template> <button :class="btnClass" :style="btnStyle" @click="handleClick"> {{ btnText }} </button> </template> <script> export default { props: { btnClass: String, btnStyle: String, isAuth: Boolean }, emits: ['action'], computed: { btnText() { return this.isAuth ? 'Sign out from Microsoft' : 'Sign in with Microsoft' } }, methods: { handleClick() { this.$emit('action') } } } </script>
第二步:修正父组件动态挂载逻辑
propsData仅传props值,事件通过$on绑定,逻辑放到事件回调里执行:
insertBtnComponent() { const ComponentClass = Vue.extend(buttonVue) const instance = new ComponentClass({ propsData: { btnClass: "buttonMs", btnStyle: "position: static;", isAuth: this.isUserAuthenticated() } }) // 绑定自定义事件 instance.$on('action', () => { this.isUserAuthenticated() ? this.signOut() : this.signInUser() }) const selector = document.querySelector(".classNAMEofDiv"); instance.$mount() selector.appendChild(instance.$el) // 组件移除前记得调用 instance.$destroy() 避免内存泄漏 }
额外注意事项
- 不要在props里传执行后的函数结果,需要传回调的话直接传函数引用,不要加括号调用。
- Vue单向数据流规则要遵守:父传子用props,子通知父用emit,不要试图通过emit反向获取父组件数据。
- 动态创建的组件实例在不需要时必须手动调用
$destroy()销毁,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Nurbek Ss
相关产品推荐
相关产品推荐

