Vue中能否从$emit获取返回值?求可行解决方案
Vue中$emit无法获取父组件方法返回值的原因及替代方案
$emit本身不支持返回值
Vue的$emit是事件触发机制,它的作用只是向父组件发送事件通知,本身返回的是一个布尔值(表示是否有父组件监听了该事件),完全不支持返回父组件方法的执行结果。
你代码里的问题:
await this.$emit(...)无效,因为$emit返回的不是Promise,无法用await等待结果;- 尝试通过传变量
data获取结果失败,是因为父组件里data = { ...newData }是重新给参数变量赋值,并没有修改子组件原变量的引用,子组件的data还是初始的null。
可行的替代方案
方案1:父组件通过props回传结果
父组件执行完方法后把结果存在自身data中,再通过props传给子组件,子组件监听props变化获取结果:
子组件代码:
<template> <!-- 子组件内容 --> </template> <script> export default { props: ['loadedData'], watch: { loadedData(newVal) { if (newVal) { // 拿到父组件回传的结果,处理业务逻辑 console.log(newVal); } } }, methods: { fetchData() { this.$emit('loadData', this.Id); } } } </script>
父组件代码:
<template> <ChildComponent :loadedData="userData" @loadData="loadData" /> </template> <script> export default { data() { return { userData: null } }, methods: { async loadData(Id) { let newData = await this.$store.dispatch('user/loadUserData', Id); this.userData = { ...newData }; } } } </script>
方案2:子组件直接调用store action(逻辑允许时)
如果数据获取逻辑不需要父组件介入,子组件可以直接调用store的dispatch,自己拿到返回值:
<script> export default { methods: { async fetchData() { let data = await this.$store.dispatch('user/loadUserData', this.Id); // 直接拿到结果,处理业务逻辑 console.log(data); } } } </script>
方案3:通过回调函数传递结果
子组件emit时传入一个回调函数,父组件拿到数据后调用该回调把结果传回:
子组件代码:
<script> export default { methods: { fetchData() { this.$emit('loadData', this.Id, (result) => { // 拿到父组件返回的结果 console.log(result); // 处理业务逻辑 }); } } } </script>
父组件代码:
<script> export default { methods: { async loadData(Id, callback) { let newData = await this.$store.dispatch('user/loadUserData', Id); callback({ ...newData }); } } } </script>
方案4:用Promise包装emit事件
父组件监听事件时通过Promise传递结果,子组件通过await获取:
子组件代码:
<script> export default { methods: { async fetchData() { const result = await new Promise((resolve) => { this.$emit('loadData', this.Id, resolve); }); // 拿到结果,处理业务逻辑 console.log(result); } } } </script>
父组件代码:
<script> export default { methods: { async loadData(Id, resolve) { let newData = await this.$store.dispatch('user/loadUserData', Id); resolve({ ...newData }); } } } </script>
内容的提问来源于stack exchange,提问作者Jyina
相关产品推荐
相关产品推荐

