EventBus踩坑2

$on绑定事件内部的组件实例

具体现象:

在全局事件总线中使用$on触发的事件,在方法内部调用this中的data时发现,data中的值全部为初始值。无法获取到已经修改过的data中的数据。

组件1:

<template>
    <div>
        <input type="text" placeholder="请输入姓名" v-model="formData.name">
        <input type="text" placeholder="请输入年龄" v-model="formData.age">
        <button @click="submit">提交</button>
    </div>
</template>

<script>
import EventBus from "../demo";
export default {
    name: 'Component1',
    data() {
        return {
            formData:{
                name: '',
                age: '',
            }
        };
    },
    created() {
        // 清除上次的,防止被多次调用
        EventBus.$off('log');
        EventBus.$on('log',this.test);
    },
    methods: {
        submit(){
            this.$emit('submit');
        },
        test(){
            console.log(this.formData)
            // 输出结果是{name:'',age:''}
        }
    },
}
</script>

<style></style>

组件2:

<template>
    <div></div>
</template>

<script>
import EventBus from "../demo";
export default {
    name: 'Component2',
    data() {
        return {
            
        };
    },
    created() {
        // 清除上次的,防止被多次调用
        EventBus.$off('submit');
        EventBus.$on('submit',this.emit);
    },
    methods: {
        emit(){
            EventBus.$emit('log')
        }
    },
}
</script>

<style></style>

在组件1的输入框中都输入内容

然后点击提交按钮

最终调用test() 方法,发现最终打印出来的formData的值全部都是空的,此时去查看Vue dev tools发现,组件上的formData是有值的。

问题原因:

官方的原因未找到,个人推测是因为EventBus的$on触发的方法,内部的this指向的是在created生命周期时的组件实例,在那个时候,组件的所有data都是初始化的状态,因此打印出来的formData为空,Devtool中看到的是当前的组件实例。

解决方案:

  1. 使用vuex或者依赖注入替代。
  2. 传递this

组件1:

<template>
    <div>
        <input type="text" placeholder="请输入姓名" v-model="formData.name">
        <input type="text" placeholder="请输入年龄" v-model="formData.age">
        <button @click="submit">提交</button>
    </div>
</template>

<script>
import EventBus from "../demo";
export default {
    name: 'Component1',
    data() {
        return {
            formData:{
                name: '',
                age: '',
            }
        };
    },
    created() {
        // 清除上次的,防止被多次调用
        EventBus.$off('log');
        EventBus.$on('log',this.test);
    },
    methods: {
        submit(){
            // 把当前最新的组件实例传递给组件2
            this.$emit('submit',this);
        },
        // 接受到的最新的组件实例
        test(that){
            console.log(that.formData)
        }
    },
}
</script>

<style></style>

组件2:

<template>
    <div></div>
</template>

<script>
import EventBus from "../demo";
export default {
    name: 'Component2',
    data() {
        return {
            
        };
    },
    created() {
        // 清除上次的,防止被多次调用
        EventBus.$off('submit');
        EventBus.$on('submit',this.emit);
    },
    methods: {
        // 接受组件1给的this,并将这个this再次传回给组件1
        emit(that){
            EventBus.$emit('log',that)
        }
    },
}
</script>

<style></style>

如上述代码所示,在组件1中将当前最新的组件实例传递给组件2,由组件2传回给组件1,在组件1触发的方法中使用最新的组件实例上的方法和数据,此时打印出来的结果就变成了最新输入的数据。组件1对应方法中需要用到this的地方需要全部替换为that

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值