Vue组件间传值(爷传孙,孙传爷)

爷传孙

首先说明:既然你学会了父传子,那么爷传孙自然不是难事,你可以先父传子,再子传孙,一步一步传,这里不再赘述。
这里用到的方法是$attrs传参,比起上面的更简洁一些,首先我们还是来一个初始状态,先将父组件的参数在父组件自身展示一下:

<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>

注意:现在还未传参

首先我们需要先在父组件引用的子组件上使用自定义属性,将值先传给子组件,这里我们定义自定义属性:grandson

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

然后重点来了:我们此时不需要使用props在子组件接收数据,而是直接在子组件引用的孙组件上面绑定v-bind="$attrs",在这里此段代码就像导管一样,直接将数据传给了孙组件。

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

那么如果说它将数据导给了孙组件,那么我们此时就可以在孙组件内部使用props接收数据,然后我们将接收到的数据展示出来。

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

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

孙传爷

与上同理:既然你学会了子传父,那么孙传爷也不是难事,你可以先子传父,再父传爷,一步一步传,这里不再赘述。
这里用到的方法是$listeners传参,比起上面的更简洁一些,首先我们还是来一个初始状态,先将孙组件的参数在孙组件自身展示一下:

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

<script>
    export default {
        name: "GrandSon",
        data(){
            return{
                toFather:"孙组件传给父组件的值!~"
            }
        }
    }
</script>
这里给h1:"孙组件传给父组件的值!~"添加一个点击事件来触发sendToFather函数来传参:
<template>
    <div class="grandson">
        <h1>孙组件</h1>
        <h1 @click="sendToFather">{{ toFather }}</h1>
    </div>
</template>
然后在methods中处理sendToFather函数:
methods:{
            sendToFather(){
                this.$emit("father",this.toFather)
            }
        }

这里触发的是自定义事件father,后面定义,传走的值是toFather:"孙组件传给父组件的值!~"
然后重点来了:我们此时不需要使用自定义事件"father"在子组件接收数据,而是直接在子组件引用的孙组件上面绑定v-on="$listeners",在这里此段代码就像导管一样,直接将数据传给了父组件。

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

子组件部分处理完毕,再来看父组件,这里先来个坑用来接收数据,然后定义之前提到的自定义事件father,使其调用getFromGrandSon函数,然后在函数getFromGrandSon中处理数据,父组件代码如下:

<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>

此时点击子组件中的h1文字触发点击事件,执行sendToFather函数,然后触发自定义事件father,在子组件中$listeners起到导管作用,将事件传给父组件,然后父组件中的father事件被触发,执行getFromGrandSon函数,将传来的值赋给valueOfGrandSon。

 

$listeners
$listeners是在vue的2.40版本新增的。
包含了父作用域中的 (不含 .native 修饰器的)v-on事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
简单点讲它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on="$listeners" 将事件监听指向这个组件内的子元素(包括内部的子组件)。

posted @ 2022-12-11 14:01  土小狗  阅读(5110)  评论(0编辑  收藏  举报