Summary and example analysis of various situations of vue 2.0 component communication in detail

  • 2021-08-05 08:38:17
  • OfStack

Summary of various roles of Props in vue components

Component is the main content of modular development in Vue, and component communication is the soul of vue data drive. Now, four main situations are summarized as follows:

Passing data using props--inside the component


//html
<div id="app1">
  <i> Note the naming rules: only in html Internal use my-message</i>
  <child my-message=" Data transfer within components "></child>
</div>
//js
<script>
  Vue.component('child', {
    props: ['myMessage'],
    template: '<mark>{{ myMessage }}<mark/>'
  });
  new Vue({
    el: '#app1'
  })
</script>

Dynamic props communication-component and root node (between parent and child)


<div id="app2">
  <input v-model="parentMsg">
  <br>
  <child :parent-msg="parentMsg"></child>
</div>
<script>
  Vue.component('child', {
    props: ['parentMsg'],
    template: '<mark>{{ parentMsg }}<mark/>'
  });
  new Vue({
    el: '#app2',
    data: {
      parentMsg: 'msg from parent!'
    }
  })
</script>

Comparative analysis:

Example 1:


<comp some-prop="1"></comp>
// Data transfer within components, corresponding to literal syntax : Passed on 1 String "1" 

Example 2:


<comp v-bind:some-prop="1"></comp>
// Component and root node data transfer, corresponding to dynamic syntax : Pass the actual number :js Expression  

Characteristics of one-way data flow: when the attributes of parent components change, they will be transmitted to child components, otherwise, they cannot

Two cases of changing prop

Note that in JavaScript, objects and arrays are reference types, pointing to the same memory space. If prop is an object or array, changing it inside a child component will affect the state of the parent component.


// Definition 1 Partial data Property and set the  prop  As the initial value of local data 
props: ['initialCounter'],
    data: function () {
    return { counter: this.initialCounter }
    }
// Definition 1 Partial computed Property, which is derived from the  prop  Calculate the value of 
 props: ['size'],
    computed: {
    normalizedSize: function () {
    return this.size.trim().toLowerCase()
    }
    }

Subcomponent index

Although there are props and events, it is sometimes necessary to access subcomponents directly in JavaScript. To do this, you can use ref to specify 1 index ID for the child component


<div id="parent">
<!-- vm.$refs.p will be the DOM node -->
<b ref="p">hello</b>
<!-- vm.$refs.child will be the child comp instance -->
<user-profile v-for='i in 3' ref="profile"></user-profile>
</div>
<script>
var userPf=Vue.component('user-profile',{
  template:'<div>hello $refs</div>'
});
var parent = new Vue({ el: '#parent' });
//  Access subcomponents 
var child = parent.$refs.profile;
console.log(child[0]);
console.log(parent.$refs.p);
</script>

$refs is populated only after the component is rendered, and it is non-responsive. It only serves as a contingency for direct access to child components--you should avoid using $refs in templates or computed properties.

Data back transmission-custom events

The foundation of custom events is that each vue instance implements an event interface (Event interface)

The Vue event system is detached from the browser's EventTarget API. Although they operate similarly, $on and $emit are not aliases for addEventListener and dispatchEvent.

Parent components can use v-on directly to listen for events triggered by child components where they are used

Monitor: $on (eventName) Trigger: $emit (eventName)

<div id="app3">
<p>Look at the parent's data: <mark>{{t}}</mark> & the child's data: <mark>{{childWords}}</mark></p>
<child v-on:add="pChange"></child>
<child v-on:add="pChange"></child>
<child v-on:click.native="native"></child>
</div>
<script>
Vue.component('child', {
  template: `<button @click="add">{{ c }}</button>`,
  data: function () {
    return {
      c: 0,
      msg: 'I am from child\'s data'
    }
  },
  methods: {
    add: function () {
      this.c += 1;
      this.$emit('add',this.msg);
    }
  },
});
new Vue({
  el: '#app3',
  data: {
    t: 0,
    childWords: ''
  },
  methods: {
    pChange: function (msg) {
      this.t += 1;
      this.childWords=msg;
    },
    native:function () {
      alert('I am a native event ,which comes from the root element ! ');
    }
  }
})
</script>

Communication between brothers-bus for simple scenes and vuex for complex scenes


<div id="app4">
  <display></display>
  <increment></increment>
</div>
<script>
  var bus = new Vue();
  Vue.component('increment', {
    template: `<button @click="add">+</button>`,
    data: function () {
      return {count: 0}
    },
    methods: {
      add: function () {
        bus.$emit('inc', this.count+=1)
      }
    }
  });
  Vue.component('display', {
    template: `<span>Clicked: <mark>{{c}}</mark> times</span>`,
    data: function () {
      return {c: 0}
    },
    created: function () {
      var self=this;
//      bus.$on('inc', function (num) {
//        self.c = num
//      });
      bus.$on('inc', (num) =>
        this.c = num
      );
    }
  });
  vm = new Vue({
    el: "#app4",
  })
</script>

Summary: In Vue, the communication between components and between components and root nodes can be artificially the communication between father and son, and the father-son relationship is relative, that is, context-related (for example, the parent component of A component may be the child component of B component); The above four examples demonstrate the communication mechanism of different components.

Clarify the above problems and it is not difficult to understand this sentence:

Compilation scope-the contents of the parent component template are compiled in the parent component scope; The contents of a subcomponent template are compiled within the scope of a subcomponent. Distribution is compiled within the scope of the parent component


Related articles: