Vue js non child parent communication with event b

2019-08-20 04:35发布

In vue js document, there is a way to communicate between non parent child components.vue document. But when I tried this method, it did not work. Below is my code. Is there any help?

The html page:

<html>
  <body>
      <div id="app10">
          <component3 :id="id"></component3>
          <component4 :id="id"></component4>
      </div>
  </body

</html>

The js script:

var bus = new Vue();
Vue.component('component3', {
  template: `
    <div @click='change'>
      {{id}}
    </div>
  `,
  props: ['id'],
  methods: {
    change() {
      console.log('??? component3 emit');
      bus.$emit('idSelected', 3);
    }
  },
  mounted() {
  }
});

Vue.component('component4', {
  template: `
    <div>
      {{id}}
    </div>
  `,
  props: ['id'],
});

var app10 = new Vue({
  el: '#app10',
  data: function() {
    return {
      id: '?'
    }
  },
  mounted() {
    bus.$on('idSelected', function(value) {
      console.log('??? app10 click event value: ', value);
      this.id = value;
      console.log('??? this.id', this.id);
    });
  },
  methods: {
  }
});

What I want to do is: when I click the component3, its text content should change from 'question mark ?' to 'number 3'. But it does not work. Even if the 'id' from the parent data changed to '3', the 'id' of child props did not change at all. Why?

The console output:

??? component3 emit
??? app10 click event value:  3
??? this.id 3

2条回答
我想做一个坏孩纸
2楼-- · 2019-08-20 05:18

This is a scoping issue. Adjust your mounted hook as follows:

mounted() {
    const self = this; // save pointer to current 'this'
    bus.$on('idSelected', function(value) {
      console.log('??? app10 click event value: ', value);
      self.id = value; // use 'self' here
      console.log('??? this.id', this.id);
    });
  }

Otherwise you loose a reference to current 'this', because it equals to 'bus' in your event listener. Try to console.log(this === bus) inside your listener ( == true).

查看更多
爷、活的狠高调
3楼-- · 2019-08-20 05:37

The value of this is changing in your code inside your anonymous function. Use arrow function instead to keep the context of your vue instance.

var bus = new Vue();
Vue.component('component3', {
  template: `
    <div @click='change'>
      {{id}}
    </div>
  `,
  props: ['id'],
  methods: {
    change() {
      console.log('??? component3 emit');
      bus.$emit('idSelected', 3);
    }
  },
  mounted() {
  }
});

Vue.component('component4', {
  template: `
    <div>
      {{id}}
    </div>
  `,
  props: ['id'],
});

var app10 = new Vue({
  el: '#app10',
  data: function() {
    return {
      id: '?'
    }
  },
  mounted() {
    bus.$on('idSelected', (value) => {
      console.log('??? app10 click event value: ', value);
      this.id = value;
      console.log('??? this.id', this.id);
    });
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<html>
  <body>
      <div id="app10">
          <component3 :id="id"></component3>
          <component4 :id="id"></component4>
      </div>
  </body>

</html>

查看更多
登录 后发表回答