vue value transfer and event mode

1. Value transfer mode of vue

1. Father to Son Transfer
  • Property Props
//child
porops:{msg:String}
//parent
<Helloworld msg="I'm passing it on to you. child Of" />
2. The Son Delivers to You
  • Reference refs
//child
data(){
    return {
        hw:"I am a child and a parent class that can be called"
    }
}

//parent
<Helloworld ref="hw" />
this.$refs.hw
3.provide and inject to realize the value transmission

provide: is equivalent to strengthening the parent component prop

inject: is equivalent to props for enhanced version subcomponents

As long as the provision of the declaration at the upper level is provided, the data of the provider can be accessed by inject at the next level, no matter how deep it is.

Tip: provide and inject bindings are not responsive. This is deliberate. However, if you pass in a monitorable object, its properties are responsive.

If you need to pass responsive values, use values of reference types, such as {} | [].

  • Components
<template>
    <div id="app">
        <Child />
    </div>
</template>
<script>
  import Child from 'Child'
  export default{
    components:{
          Child
    },  
    provide(){
        return {
            msg:"I'm the grandparent component that I'm going to prepare for the grandparent component."
        }
    },
    data(){
      return {
      }
    },
    methods:{
    }
  }
</script>
  • Child component
<template>
    <div>
        <Child1 />
    </div>
</template>
<script>
  import Child1 from 'Child1'
  export default{
    components:{
          Child1
    }, 
    data(){
      return {
      }
    },
    methods:{
    }
  }
</script>
  • Sun Component
<template>
    <div>
      <p>{{msg}}</p>
    </div>
</template>
<script>
  export default{
    inject:['msg']
    data(){
      return {
      }
    },
    methods:{
    }
  }
</script>

2. Event mode of vue

1. Child to Father
//child
this.$emit('add',good)
//parent
<Helloworld @add="add($event)"/>
2. Between brothers
  • Component A
<template>
    <div>
        <span @click="postBrotherMsg">Brother</span>
    </div>
</template>

<script>
export default {
    name: "BrotherA",
    methods: {
        postBrotherMsg() {
            this.$parent.$emit("foo", "I'm brother. My brother took it.");
        }
    }
};
</script>
  • B Component
<template>
    <div>
        <span @click="postBrotherMsg">Brother</span>
    </div>
</template>

<script>
export default {
    name: "BrotherB",
    mounted() {
        this.$nextTick(() => {});
        this.$parent.$on("foo", val => console.log('Brother, younger brother received it. Your message is:',val));
    }
};
</script>
<style lang="scss" scoped>
</style>
  • Parent component
<template>
    <div id="app">
        <BrotherA />
        <BrotherB />
    </div>
</template>
3. Transfer between grandchildren (between generations)
1. Use $attrs and $listeners to transfer data between grandchildren components
Essential Exploration

attrs: A feature binding that contains a parent scope that is not recognized (and retrieved) as a prop (except class and style), that is, all the custom attributes that he retrieves except the receivable and element-owned attributes in prop

& dollar; listeners: contains the v-on event listener in the parent scope (excluding the. native modifier). It can be passed into internal components via v-on="$listeners" -- very useful in creating higher-level components.

  • Sun Component
<template>
    <div>
      <p @click="test2">$attrs:{{$attrs['two']}}</p>
    </div>
</template>
<script>
  import Child1 from 'Child1'
  export default{
    inheritAttrs: false,
    data(){
      return {
      }
    },
    methods:{
      test2(){
        this.$emit('test2','I'm Sun Tzu Component')
      }
    }
  }
</script>
  • Child component
<template>
    <div>
      <p @click="test1">$attrs:{{$attrs['one']}}</p>
        <Child1 v-bind="$attrs" v-on="$listeners"/>
    </div>
</template>
<script>
  import Child1 from 'Child1'
  export default{
    components:{
          Child1
    },  
    inheritAttrs: false,
    data(){
      return {
      }
    },
    methods:{
      test1(){
        this.$emit('test1','I am a son component')
      }
    }
  }
</script>
  • Components
<template>
    <div id="app">
        <Child :one="child1" :two="child2" @test1="onTest1" @test2="onTest2"/>
    </div>
</template>
<script>
  import Child from 'Child'
  export default{
    components:{
          Child
    },  
    data(){
      return {
        one:"I am child1",
        two:"I am child2"
      }
    },
    methods:{
      onTest1(val){
        conosle.log("I was received by my father. test1 event callbacks",val)
      },
      onTest2(val){
        conosle.log("I was received by my father. test2 event callbacks",val)
      }
    }
  }
</script>

Summary: Can be used to pass values and events from descendant components

2. Implementing descendant-to-ancestor value by dispatch function
//In main.js
Vue.prototye.dispatch = dispatch;
/**
eventName Dispatch event name
data Disseminated data
**/
function dispatch(eventName,data){
    let parent = this.$parent
    while(parent){
        parent.$emit(eventName,data)
        parent =  parent.$parent;
    }
}
  • Descendant component
<template>
    <div>
      <p @click="dispatch('hello','hello world')">{{msg}}</p>
    </div>
</template>
<script>
  export default{
    data(){
      return {
      }
    },
    methods:{
    }
  }
</script>
  • Ancestor component
<template>
    <div id="app">
        <Child />
    </div>
</template>
<script>
  import Child1 from 'Child1'
  export default{
    components:{
          Child1
    }, 
    data(){
      return {
      }
    },
    mounted(){
        this.$on('hello',(val)=>console.log(val))
    },
    methods:{
    }
  }
</script>
3. Use Event Bus
  • main.js
class Bus{
    constructor(){
        this.callbacks = {}
    }
    $on(name,fn){
        this.callbacks[name] =  this.callbacks[name] || []
        this.callbacks[name].push(fn)
    }
    $emit(name,args){
        if(this.callbacks[name]){
            this.callbacks[name].forEach(cb=>cb(args))
        }
    }
}
Vue.prototype.$bus = new Bus()
  • Component A
<template>
    <div>
      <p @click="test1">{{msg}}</p>
    </div>
</template>
<script>
  export default{
    name:"ComA",
    data(){
      return {
      }
    },
    methods:{
      test1(){
        this.$bus.$emit('foo')
      }
    }
  }
</script>
  • B Component
<template>
    <div id="app">
      <ComA />
    </div>
</template>
<script>
  export default{
    data(){
      return {
      }
    },
    mounted(){
        this.$on('msg',(val)=>console.log(val))
    },
    methods:{
    }
  }
</script>

The last one uses Vuex, but vuex is bigger. We will keep up with it later. Please look forward to it.

Keywords: Javascript Vue

Added by prudens on Fri, 23 Aug 2019 12:32:27 +0300