a communication component vue

First, the relationship between components

1, the parent-child relationship

2, brotherhood

3, inter-generational relations

 

Second, the communication between the components

1、props
2、$emit/$on
3, VUEX
4、$parent/$children
5、$attrs/$listeners
6、provide/inject
 
Third, the communication system of example
 
Create a process using webpack to manage the project.

 

 Method One: props / $ emit

1, props --- parent component subassembly to pass values
Subcomponents: sub1.vue
Parent component: app.vue
Parent component subassembly to pass downwardly through the props. Note: There are three components in the form of data: data, props, computed
// app.vue parent component

<template>
    <div>
        <sub1 v-bind:data_from_app = "msg_parent"></sub1>
    </div>
</template>

<script>
import sub1 from './components/sub1.vue';

export default {
    data(){
        return {
            msg_parent: 'parent element data app'
        }
    },
    components:{
        sub1
    }
}
</script>

<style lang="scss" scoped>

</style>

  

// subassembly sub1.vue  

<template>
    <div>
        <p>{{data_from_app}}</p>
    </div>
</template>

<script>
export default {
    data(){
        return {
            sub_msg: 'sub1 subassembly data',
        }
    },
    props:{
        data_from_app:{
            type:String,
            require:true
        }
    }
}

// parent component subassembly to pass downwardly through the props. Note: There are three components in the form of data: data, props, computed
</script>

<style lang="scss" scoped>

</style>

  

2, sub-assemblies to the parent component by value --- (in the form of events) --- $ emit

Subassembly by sending a message to the parent component events, is to actually send data to their parent component $ $ event transmission received EMIT

// subassembly sub1.vue

<template>
    <div>
        <p>{{data_from_app}}</p>
        <p @click="changeText">{{text_sub}}</p>
    </div>
</template>

<script>
export default {
    data(){
        return {
            sub_msg: 'sub1 subassembly data',
            text_sub: 'original data sub-assembly'
        }
    },
    props:{
        data_from_app:{
            type:String,
            require:true
        }
    },
    methods:{
        changeText(){
            // custom event, pass the value "subcomponent pass values ​​to the parent component." 
            this. $ emit ( 'titleChanged', 'sub-assembly to the parent component by value')
        }
    }
}
// 1、props
// parent component subassembly to pass downwardly through the props. Note: There are three components in the form of data: data, props, computed
</script>

<style lang="scss" scoped>

</style>

  

// parent component app.vue

<template>
    <div>
        <-! Subassemblies to define a click event changeText,
        At time defined subassembly using EMIT $ titleChanged and transfer assembly to pass parameters to the parent, the sub-assembly for data to pass arguments EMIT $ ->
        <sub1 v-on:titleChanged="updateText" v-bind:data_from_app = "msg_parent"></sub1>
        <! - parent component by receiving transmitted over $ event parameter updateText ($ event) ->
        <! - here to be consistent with the sub-assembly titleChanged ->
    </div>
</template>

<script>
import sub1 from './components/sub1.vue';

export default {
    data(){
        return {
            msg_parent: 'parent element data app',
            text: 'parent component original text'
        }
    },
    methods:{
        updateText(e){
            this.text = e;
            console.log(this.text)
        }
    },
    components:{
        sub1
    }
}
</script>

<style lang="scss" scoped>

</style>

  

Method two, $ emit / $ on

This method Vue examples of an empty central bus event (Event Center), and use it to listen for events triggering event, lightweight is achieved clever communication between any of the components, including his son, brother, grandparents. When the project is large, consider using vuex.

Method to realize:

var Event = new View ()
. Event $ emit (event name, data);
. Event $ on (event name, data => {});

  

<div id="itany">
    <my-a></my-a>
    <my-b></my-b>
    <my-c></my-c>
</div>
<template id="a">
  <div>
    <h3>A组件:{{name}}</h3>
    <Button @ click = "send"> send data to a component C </ button>
  </div>
</template>
<template id="b">
  <div>
    <H3> B component: {{age}} </ h3>
    <Button @ click = "send"> array to a component C </ button>
  </div>
</template>
<template id="c">
  <div>
    <h3>C组件:{{name}},{{age}}</h3>
  </div>
</template>
<script>
var Event = new Vue (); // define an empty instance Vue
have A = {
    template: '#a',
    data() {
      return {
        name: 'tom'
      }
    },
    methods: {
      send() {
        Event.$emit('data-a', this.name);
      }
    }
}
There are B = {
    template: '#b',
    data() {
      return {
        age: 20
      }
    },
    methods: {
      send() {
        Event.$emit('data-b', this.age);
      }
    }
}
There are C = {
    template: '#c',
    data() {
      return {
        name: '',
        age: ""
      }
    },
    mounted () {// performed after the completion of the template compilation
     Event.$on('data-a',name => {
         this.name = name; // internal function arrows no new this, here, if not =>, this refers to Event
     })
     Event.$on('data-b',age => {
         this.age = age;
     })
    }
}
was vm = new Vue ({
    el: '#itany'
    components: {
      'my-a': A,
      'my-b': B,
      'my-c': C
    }
});    
</script>

  

$ On the monitor custom events and data-a data-b, because sometimes uncertain when it will trigger an event, usually listens mounted hooks or created

 

Method three, vuex

 

 

vuex principle:

vuex implements a one-way data flow, data stored in the State has a global, when the components you want to change the data in the State, must be made through mutation, mutation while providing subscribers mode for external plug-in call to get updated State data. And when all asynchronous operations (common in backend interface asynchronous call to get an update) or batch synchronization operations need to take Action, but the Action state can not be modified directly, or the need to modify the data state by mutation. Finally, according to the change of state, to render the view.

Each module description:

  • Vue Components: Vue components. HTML page, interactions responsible for receiving user operation, execute dispatch method triggers a corresponding action in response.
  • dispatch: operating behavior trigger method is the only method capable of performing the action.
  • actions: operational behavior processing module assembly by $store.dispatch('action 名称', data1)triggered. Then the commit () call to trigger mutation, indirect updated State . Responsible for handling all interactions Vue Components received. Comprising synchronous / asynchronous operation, support the methods of the same name, which in turn triggers the order of registration. Request to the backend API operations on in this module, including trigger other action and submit the operation mutation. This module provides Promise package to support the action triggered a chain.
  • commit: commit operation state change method. Submit to mutation, it is the only way to perform mutation of.
  • mutations: status change operation method, by the actions of commit('mutation 名称')a trigger . Is the only recommended method Vuex modify the state. This method can only operate synchronously, and the method name can only be globally unique. Among the operation there will be some hook exposed to monitor the state and so on.
  • state: Page Status Management container object. Vue components centrally stored in data objects scattered data, globally unique, unified state management. Page required to display data read from the subject, using the fine-grained data Vue response mechanism to perform efficient update.
  • getters: state method for reading objects. FIG not separately listed in the module, should be included in the render in, Vue Components read global target state by this method.

vuex is vue state management, data storage is responsive, but not saved, then refresh returned to the initial state. Specifically there should be at vuex copy data changes the data stored in the localStorage, after refreshing, if there localstorage saved data, taken out state replace the inside of the store

 

Method four: $ attrs / $ listeners

$ Attrs: parent contains the scope, the prop is not identified (and obtain) the binding properties (class and style excluded), when a component does not declare any prop, this will contain all the binding parent scope (except for class and style), and can be v-bind = "$ attrs" incoming internal components. Usually used in conjunction with interitAttrs option.

$ Listeners: contains the parent scope (excluding .native decorator) v-on event listener. He can be v-on = "$ listeners" Incoming internal components

// app.vue outermost assembly itself defines three data foo boo coo
// At this time, inside the sub-assembly is sub1, for it uses three foo boo coo data, but only defines itself sub1 this property foo

<template>
    <div>
        <-! Subassemblies to define a click event changeText,
        At time defined subassembly using EMIT $ titleChanged and transfer assembly to pass parameters to the parent, the sub-assembly for data to pass arguments EMIT $ ->
        <P> data parent components: foo: {{foo}}, boo: {{boo}}, coo: {{coo}} </ p>
        <sub1 :foo="foo"
              :boo="boo"
              :coo="coo"
              v-on:titleChanged="updateText" 
              v-bind:data_from_app = "msg_parent"></sub1>
        <! - parent component by receiving transmitted over $ event parameter updateText ($ event) ->
        <! - here to be consistent with the sub-assembly titleChanged ->

        <!-- <subvue1></subvue1>
        <subvue2></subvue2> -->


    </div>
</template>

<script>
import sub1 from './components/sub1.vue';
// import subvue1 from './components/subVue/subvue1.vue';
// import subvue2 from './components/subVue/subvue2.vue';

export default {
    data(){
        return {
            msg_parent: 'parent element data app',
            text: 'parent component original text',
            foo:'html',
            boo:'css',
            coo 'view'
        }
    },
    methods:{
        updateText(e){
            this.text = e;
            console.log(this.text)
        }
    },
    components:{
        sub1,
        // subvue1,
        // subvue2
    }
}
</script>

<style lang="scss" scoped>

</style>

  

// sub1 APP sub-components, itself only defines the foo property, and therefore by $ attrs got the boo coo
// Here sub1 have a sub-assembly subvue1, to that child using the $ attrs, namely boo coo, but only boo property itself subassembly

<template>
    <div>
        <p>{{data_from_app}}</p>
        <p @click="changeText">{{text_sub}}</p>
        <p>foo:{{foo}}</p>
        <p>sub1的$attrs:{{$attrs}}</p>
        <subvue1 v-bind="$attrs"></subvue1>
    </div>
</template>

<script>
import subvue1 from './subVue/subvue1.vue'
export default {
    data(){
        return {
            sub_msg: 'sub1 subassembly data',
            text_sub: 'original data sub-assembly'
        }
    },
    inheritAttrs: false, // can be mounted automatically to shut down the props not declared property on the root element
    props:{
        data_from_app:{
            type:String,
            require:true
        },
        foo:String
    },
    created(){
        console.log(this.$attrs);
    },
    methods:{
        changeText(){
            // custom event, pass the value "subcomponent pass values ​​to the parent component." 
            this. $ emit ( 'titleChanged', 'sub-assembly to the parent component by value')
        }
    },
    components:{
        subvue1
    }
}
// 1、props
// parent component subassembly to pass downwardly through the props. Note: There are three components in the form of data: data, props, computed
</script>

<style lang="scss" scoped>

</style>

  

// subvue1 sub1 sub-assembly, and it defines itself only a boo this property, so attrs got the coo  

<template>
    <div>
        <H3> subvue1 assembly </ h3>
        <p>boo:{{boo}}</p>
        <-! <Button> subvue1 components: the data to the component subvue2 </ button> ->
        <p>subvue1的$attrs:{{$attrs}}</p>
    </div>
</template>

<script>
Import View from 'view';

export default {
    data(){
        return {
            data1:'subvue1',
            data_from:''
        }
    },
    props:{
        boo:String
    },
    mounted(){

    },
    created9(){
        console.log(this.$attrs);
    },
    methods:{
   
    }
}
</script>

<style lang="sass" scoped>

</style>

  

 

 Summary: $ attrs indicates data not inherited object format is {attribute name: attribute value}, vue2.4 provided $ attrs, $ listeners to pass data and practice, the communication between cross-level assembly easier.

$ Attrs which is stored in the parent component of the non-binding properties props. $ Listeners stored inside a non-native binding in the event the parent component.

 

Method five: provide / inject

Both need to be used together. Component injection allows an ancestor to all future generations a dependent, regardless of how deep the component level, and always take effect on downstream relationships established time. It is: to provide a variable component ancestor by provide, then injected in the descendants component variables inject.

Mainly to solve the communication problems in cross-level assembly, but his usage scenario, mainly sub-assembly components to obtain higher status, the establishment of cross-level assembly between unsolicited and Dependency Injection relationship.

// A.vue
export default {
  provide: {
    name: 'waves in the boating'
  }
}

  

// B.vue
export default {
  inject: ['name'],
  mounted () {
    console.log (this.name); // waves in the boating
  }
}

  

provide / inject binding is not responsive, this is deliberate. If you pass a listener object, then the object or its properties can respond. So, A.vue the name change, B.vue of this.name will not change.

 

Method six: $ parent / $ children with ref

ref: If in ordinary dom element, reference is directed dom element; if used in the subassembly, to a reference to a component instance.

$ Parent / $ children access to the Father, Son examples

The above two methods are examples of components, the component can invoke a method to use or access data.

Drawbacks: You can not cross-level communication between the brothers or

// component-a subassembly
export default {
  data () {
    return {
      title: 'Vue.js'
    }
  },
  methods: {
    sayHello () {
      window.alert('Hello');
    }
  }
}

  

// parent component
<template>
  <component-a ref="comA"></component-a>
</template>
<script>
  export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.title);  // Vue.js
      comA.sayHello (); // pop
    }
  }
</script>

  

IV Summary

  • Father and son communication:

Transmitted to the parent sub-data by props, by the child to the parent Events ( $emit); by the parent chain / daughter strand may also communicate ( $parent /  $children); REF can also access the component instance; provide / inject API;$attrs/$listeners

  • Brothers communication:

Bus;Vuex

  • Mataga级 communication:

Bus;Vuex;provide / inject API、$attrs/$listeners

 

Guess you like

Origin www.cnblogs.com/1220x/p/11741332.html