Vue中this在data return function以及mounted函数中的指向问题

由官网教程《非父子组件的通信》部分引发的测试和思考:
大致就是建立两个子组件,组件a的值传给组件b。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Vue组件</title>
    <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body> 
    <div id="example-7">
        <p>非父子组件的通信:</p>
        <p>有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的Vue实例作为事件总线。</p>
        <a-component></a-component>
        <b-component></b-component>
    </div>
</body>
<script>
    //非父子组件的通信
    let bus = new Vue();
    Vue.component("a-component", {
        template: `<button @click="idSelected">传递组件A的值</button>`,
        methods: {
            //June[Question]这里的this指?
            idSelected: function () {
                bus.$emit("id-selected", 1);//触发组件A中的事件
            }
        }
    });
    Vue.component("b-component", {
        data() {
            //June[Question]这里的this指?
            console.log(this);
            return {
                value: ""
            }
        },
        template: `<p v-model='value'>组件B接收到组件A的值为:{{value}}</p>`,
        //June[Question]mounted和methods的区别
        mounted() {
            //监听组件A的事件,并接收其传递的数据
            bus.$on("id-selected", function (id) {
                console.log(this);
                this.value = id;
                console.log("组件B接收到组件A的值为:" + id);
                //如果绑定this上下文的话,this为 o {_uid: 30, _isVue: true, $options: {…}, _renderProxy: o, _self: o, …}
            // }.bind(this));
            //如果不绑定this上下文的话,value属性拿不到,this为 hn {_uid: 27, _isVue: true, $options: {…}, _renderProxy: hn, _self: hn, …}
        });
        }
    });
    let example7 = new Vue({
        el: "#example-7"
    });

</script>
</html>

demo就是想要在点击组件A的按钮“传递组件A的值”时,emit函数里可以传递数字1给组件B,组件B再把它赋值给自己的属性,然后显示在页面上。传递不是问题,不过发现一开始不对B内的bus.$on的回调函数绑定this,会无法对组件B中的value进行赋值,所以怀疑this指向的问题,所以打印出了this.

 bus.$on("id-selected", function (id) {
                console.log(this);
                this.value = id;
                console.log("组件B接收到组件A的值为:" + id);
 });
      

图片描述
图片描述

可以发现组件B内是可以获取到传递的id值的,但是组件B的value并没有赋值成功,而$on匿名函数内的this指向跟data(){}中的this指向不同,也就是说作用域不同,导致value无法被赋值成功。

当对组件B的匿名函数绑定this时,

 bus.$on("id-selected", function (id) {
                console.log(this);
                this.value = id;
                console.log("组件B接收到组件A的值为:" + id);
 }.bind(this));
      

图片描述
图片描述

可以发现这次组件B的value可以被赋值成功了,而this的指向也相同了。

Question?

1.我的理解是this是绑定到了全局window对象了,才实现赋值,对吗?
2.谁解释下o{_uid:30.....},hn{_uid:27...}是什么意思?

谢谢!

阅读 6.1k
2 个回答

template: <p v-model='value'>组件B接收到组件A的值为:{{value}}</p> 中的value 应该是注册在example7.$children上的。
所以

bus.$on("id-selected", function (id) {
        console.log(this);
        this.value = id;
        console.log("组件B接收到组件A的值为:" + id);
 }

中this的指向不用应该是bus 而应该是example7
所以改成以下就好了

bus.$on("id-selected", (id) => {
        console.log(this);
        this.value = id;
        console.log("组件B接收到组件A的值为:" + id);
 }
  1. vue是帮你把当前vue实例的methods,created等里面的直接this处理成了当前vue实例,可是你的this是回调函数的呀(回调函数里的this应该是你作为bus的vue实例,应该是在$on的时候做了处理,就像jquery的事件绑定会帮你处理this一样)。
  2. _uid是vue实例的编号,每个实例都有,不重复。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题