Passing values between Vue components (super full, cross-generation) from father to son, from son to father, from grandfather to grandson, from grandson to grandson, nanny-level explanation

foreword

After reading a lot of posts about passing parameters between vue components, I found that many are incomplete. I have nothing to do today to summarize the value passing between vue components. This article involves: father to son, son to father, father to grandson, grandson to grandpa The value transfer between components is written in more detail. Students, don’t think I’m wordy. This article should have reached the nanny level. If you don’t understand it, come and hit me.
The three components used this time are named: Father, Son, GrandSon.

Preparation

First look at the code of the next three components:

1. Parent component

<template>
    <div class="father">
        <h1>父组件</h1>
        <Son></Son>
    </div>
</template>

2. Subcomponents

<template>
    <div class="son">
        <h1>子组件</h1>
        <GrandSon></GrandSon>
    </div>
</template>

3. Sun component

<template>
    <div class="grandson">
        <h1>孙组件</h1>
    </div>
</template>

For the convenience of distinguishing, here is a brief description of the style, and the rendering effect is as shown in the figure:
insert image description here

pass value between components

1. From father to son

First render the value in the parent component toSoninside the parent component.

<template>
    <div class="father">
        <h1>父组件</h1>
        <h1>{
   
   {toSon}}</h1>
        <Son></Son>
    </div>
</template>

<script>
    import Son from './Son.vue'
    export default {
      
      
        name: "Father",
        components:{
      
       Son },
        data(){
      
      
            return{
      
      
                toSon:"这是父组件传给子组件的值!~"
            }
        }
    }
</script>

Notice:这里还没有进行传参
insert image description here

As we all know: passing from father to son is to use custom attributes to pass parameters and use propsreceived data.
We define custom properties at child components used in parent components :son.

<Son :son="toSon"></Son>

Then we receive data in the subcomponent, and the received data must correspond to sonthe previous custom properties :son.

props: {
    
    
            son:String
        },

It can also be written like this:

        props:["son"],

The first way of writing can specify the received data type or default value, and the second way of writing is more convenient, you can directly add commas to the back row in the form of an array.
We then use the received data in child components.

<template>
    <div class="son">
        <h1>子组件</h1>
        <h1>{
   
   {son}}</h1>
        <GrandSon></GrandSon>
    </div>
</template>

Then the father-to-son is completed, as shown in the figure:
insert image description here

2. child father

First, the value of the child component that needs to be passed to the parent component is rendered inside the child component:

<template>
    <div class="son">
        <h1>子组件</h1>
        <h1>{
   
   {toFather}}</h1>
        <GrandSon></GrandSon>
    </div>
</template>

<script>
    import GrandSon from './GrandSon.vue'
    export default {
      
      
        name: "Son",
        components:{
      
       GrandSon },
        data(){
      
      
            return{
      
      
                toFather:"这是子组件传给父组件的值!~"
            }
        }
    }
</script>

Notice:这里还没有传参
insert image description here

Passing from child to father relies on custom events, which is used to receive data $emit.
Here we h1add a click event to call sendToFatherthe method, which will be used to trigger our custom events later.

<template>
    <div class="son">
        <h1>子组件</h1>
        <h1 @click="sendToFather">{
   
   {toFather}}</h1>
        <GrandSon></GrandSon>
    </div>
</template>

Then methodshandle this method in:

methods:{
    
    
            sendToFather() {
    
    
                this.$emit("father",this.toFather)
            }
        }

fatherIt means that after we trigger the click event to call the function sendToFather, a custom event will be triggered father, this.toFatherindicating the value to be passed to the parent component in the child component.
After the child component is processed, we enter the parent component. We need to add a custom event at the position where the parent component calls the child component, fatherand then the function getFromSoncan receive the incoming data. In order to be more intuitive, we first put a pit valueOfSonto receive the data. The parent component code is as follows:

<template>
    <div class="father">
        <h1>父组件</h1>
        <h1>{
   
   {valueOfSon}}</h1>
        <Son @father="getFromSon"></Son>
    </div>
</template>

<script>
    import Son from './Son.vue'
    export default {
      
      
        name: "Father",
        components:{
      
       Son },
        data(){
      
      
            return{
      
      
                valueOfSon:"子组件接收数据的坑~"
            }
        },
        methods:{
      
      
            getFromSon(val){
      
      
                this.valueOfSon=val
            }
        }
    }
</script>

未传值时, the page is as shown in the figure:
insert image description here

Then we click in the child component h1: 这是子组件传给父组件的值!~ , trigger sendToFatherthe function, then trigger the custom event father, pass the value away, trigger the event toFatherin the parent component , call the function, pass the received value , and we will find that the remaining pit data changes to , the value is passed successfully.fathergetFromSonvalueOfSon这是子组件传给父组件的值!~
insert image description here

3. Grandchildren

First of all, let me explain: since you have learned how to pass from father to son, it is not difficult to pass on from father to son. You can pass it on from father to son, and then from son to grandson, step by step, so I won’t go into details here.
The method used here is $attrsto pass parameters, which is more concise than the above ones. First of all, we still come to an initial state, and first display the parameters of the parent component in the parent component itself:

<template>
    <div class="father">
        <h1>父组件</h1>
        <h1>{
   
   {toGrandSon}}</h1>
        <Son></Son>
    </div>
</template>

<script>
    import Son from './Son.vue'
    export default {
      
      
        name: "Father",
        components:{
      
       Son },
        data(){
      
      
            return{
      
      
                toGrandSon:"父组件传给孙组件的值!~"
            }
        },
    }
</script>

Notice:现在还未传参
insert image description here

First of all, we need to use custom properties on the child component referenced by the parent component, and pass the value to the child component first. Here we define custom properties :grandson.

<template>
    <div class="father">
        <h1>父组件</h1>
        <h1>{
   
   {toGrandSon}}</h1>
        <Son :grandson="toGrandSon"></Son>
    </div>
</template>

Then comes the important point: we don’t need to use propsthe subcomponent to receive data at this time, but bind directly on the grandchild component referenced by the subcomponent v-bind="$attrs". Here this code is like a conduit, directly passing the data to the grandchild component.

<template>
    <div class="son">
        <h1>子组件</h1>
        <GrandSon v-bind="$attrs"></GrandSon>
    </div>
</template>

So if it is said that it leads the data to the grandson component, then we can use the propsreceived data inside the grandchildren component at this time, and then we will display the received data.

<template>
    <div class="grandson">
        <h1>孙组件</h1>
        <h1>{
   
   { grandson }}</h1>s
    </div>
</template>

<script>
    export default {
      
      
        name: "GrandSon",
        props:{
      
      
            grandson:String
        }
    }
</script>

Received successfully, the effect is as shown in the figure:
insert image description here

4. Sun Chuanye

The same as above: since you have learned how to pass on from son to father, it is not difficult to pass on to grandson from father to son. You can pass it on from son to father first, then from father to father, step by step, so I won’t go into details here.
The method used here is $listenersto pass parameters, which is more concise than the above ones. First of all, we still come to an initial state, and first display the parameters of the grandson component in the grandson component itself:

<template>
    <div class="grandson">
        <h1>孙组件</h1>
        <h1>{
   
   { toFather }}</h1>
    </div>
</template>

<script>
    export default {
      
      
        name: "GrandSon",
        data(){
      
      
            return{
      
      
                toFather:"孙组件传给父组件的值!~"
            }
        }
    }
</script>

insert image description here

Here h1: "孙组件传给父组件的值!~"Add a click event to trigger sendToFatherthe function to pass parameters:

<template>
    <div class="grandson">
        <h1>孙组件</h1>
        <h1 @click="sendToFather">{
   
   { toFather }}</h1>
    </div>
</template>

Then methodshandle sendToFatherthe function in:

methods:{
    
    
            sendToFather(){
    
    
                this.$emit("father",this.toFather)
            }
        }

What is triggered here is a custom event father, which is defined later, and the passed value is toFather:"孙组件传给父组件的值!~"
then the key point: we don't need to use the custom event "father" to receive data in the subcomponent, but directly on the grandchild component referenced by the subcomponent Binding v-on="$listeners", where this piece of code acts like a conduit, passing data directly to the parent component.

<template>
    <div class="son">
        <h1>子组件</h1>
        <GrandSon v-on="$listeners"></GrandSon>
    </div>
</template>

After the sub-components are partially processed, let’s look at the parent component. Here is a pit to receive data, and then define the custom event mentioned earlier to make it fathercall getFromGrandSona function, and then getFromGrandSonprocess the data in the function. The code of the parent component is as follows:

<template>
    <div class="father">
        <h1>父组件</h1>
        <h1>{
   
   { valueOfGrandSon }}</h1>
        <Son @father="getFromGrandSon"></Son>
    </div>
</template>

<script>
    import Son from './Son.vue'
    export default {
      
      
        name: "Father",
        components:{
      
       Son },
        data(){
      
      
            return{
      
      
                valueOfGrandSon:"接收孙组件传参的坑~"
            }
        },
        methods:{
      
      
            getFromGrandSon(val){
      
      
                this.valueOfGrandSon=val
            }
        }
    }
</script>

When no parameters are passed, as shown in the figure:
insert image description here

At this time, clicking the text in the subcomponent h1triggers the click event, executes sendToFatherthe function, and then triggers the custom event , which acts as a conduit fatherin the subcomponent, passes the event to the parent component, and then the event in the parent component is triggered, the function is executed, and the The passed value is assigned to . as the picture shows:$listenersfathergetFromGrandSonvalueOfGrandSon

insert image description here

OK! ~, you're done, here father to son, son to father, father to grandson, grandson to grandson, and grandpa to grandson is over, let's do some small expansion below, students who have already understood can skip it.

expand

  • 只是自己的一点见解,如有错误欢迎指正。

1. Custom attributes

  • In vue, we often use some dynamic attributes, such as :class, :id, :src, :key, etc.
    These attributes have a common feature that is: they are all stipulated by the system and have specific functions, such as :classfollowed by values, which can be dynamic The class to bind this element to.
    These attributes I collectively refer to as: 系统自带的属性.
  • And some attributes are written by ourselves, such as the above :sonand above :grandson, these attributes are only known to us what they are used for, and you can even write them :abcto :qwerdfdefine these attributes.
    These attributes I collectively refer to as: 自定义属性.
  • 需要强调的是,使用父传子或者爷传孙的时候,一定要使用自定义属性,如果你使用了系统自带的属性来传参是万万行不通的。

2. Custom events

  • In vue, we also often use some events, such as @click, @dbclick, @keyup, @keydowmetc.
    These events have a common feature that is: they are all stipulated by the system and have specific functions, for example, it @clickis stipulated that you click on a certain area to trigger the function to be executed later.
    Such events, I collectively refer to as: 系统自带的事件.
  • And some events are written by ourselves. As mentioned above @father, only we know when these events are triggered. The trigger mechanism above is written in the click event. You can also have more choices. You can even Can be written @abcto @qwerdfdefine these events.
    Such events, I collectively refer to as: 自定义事件.
  • 需要强调的是,使用子传父或者孙传爷的时候,一定要使用自定义事件,如果你使用了系统自带的事件来传参也是万万行不通的。

3.$attrs

  • $attrsIt was added in version 2.40 of vue.
  • Contains attribute bindings ( and exceptions) that are not proprecognized (and acquired) in the parent scope. When a component doesn't declare any , all parent scope bindings ( except and ) are included here, and can be passed to inner components - useful when creating high-level components.classstylepropclass stylev-bind="$attrs"
  • Simply put, it includes all the properties set by the parent component on the child component (except propthe passed properties, classand style).

4.$listeners

  • $listenersIt was added in version 2.40 of vue.
  • Contains event listeners (without .nativethe decorator) in the parent scope. v-onIt can be v-on="$listeners"passed to internal components via -very useful when creating higher level components.
  • To put it simply, it is an object that contains all the listeners (event listeners) that act on this component. You can point the v-on="$listeners" event listener to the sub-elements in this component (including internal sub-components).

5. inheritAttrs

  • inheritAttrsIt was added in version 2.40 of vue.
  • type: boolean
  • Defaults:true
  • If the parent component passes data to the child component, and the child component does not use the receiver, then the data will be used propsas the attributes of the HTML element of the child component, and these attributes are bound to the HTML root element of the component.
  • If you don't want the root element of this component to inherit from the parent component attribute, and the attributes passed by the parent component (not propsreceived by the child component), you don't want to be displayed on the dom element of the child component inheritAttrs: false, but you can use it in the child component By $attrsobtaining unused registration attributes, the binding of inheritAttrs: falsestyle and will not be affected class.

Such as: I bind custom properties in the parent component :abcand receive datamsg:"666"

<Son :abc="msg"></Son>
data(){
    
    
    return{
    
    
         msg:"666"
     }
}

If props reception is not applicable in subcomponents, we will see such a situation: custom properties are rendered on the div of subcomponents.

<div class="son" abc="666">
     <h1>子组件</h1>
</div>

And if we add inheritAttrs: false, as follows:

export default {
    
    
        name: "Son",
        inheritAttrs: false,
        components:{
    
     GrandSon },
    }

It will be rendered as follows, and the custom attributes disappear.

<div class="son">
     <h1>子组件</h1>
</div>

Note: The pair inheritAttrsoperation does not affect our $attrsuse of the pair.

epilogue

The article is over here. If you have learned something here, I hope you can give me a like, comment and bookmark. Thank you very much for your support. I will continue to write in a serious manner on the road to blogging.加油 ♪(・ω・)ノ

Guess you like

Origin blog.csdn.net/SJJ980724/article/details/120829650