多层传值:
在不用状态管理vuex的时候,如何让父组件与子孙组件通信,我们可以用可以 $emit一层一层的传递:会显得冗余。 vue2.4之后,提出 $attrs、$listeners ,可以实现跨级组件通信。
-
$listeners官网解说:事件传递(接收父组件传的所有的属性值) -
$attrs官网解说:属性传递(将要触发的监听器让父组件去绑定)
在组件中绑定 ,可以把当前组件的自定义属性和方法传给子元素使用:
one组件:<two v-bind:xx="100" v-on:twoEvent="fn"></two>
two组件中:<three v-bind="$attrs" v-on="$listeners"></three>
three组件:可以访问two的 属性和触发事件: {{this.$attrs.xx}} this.$emit("twoEvent",20)
案例:
父组件:
<template>
<div class="app">
<h1>{{msg}}</h1>
<button @click="change">点击修改app组件的msg</button>
<!-- 父向子传值:属性传值 -->
<!-- 子向父传值:自定义事件 -->
<Box :b="msg" @x="change1"></Box>
</div>
</template>
<script>
import Box from "@/components/Box.vue"
export default {
data(){
return {
msg:"app组件的数据"
}
},
methods:{
change(){
this.msg="hello"
},
change1(arg){
console.log(arg)
this.msg=arg
}
},
components:{
Box,
}
}
</script>
<style lang="scss">
.app{
width:400px;
height: 400px;
background-color: aqua;
margin: 20px;
}
</style>
子组件:
<template>
<div class="box1">
<h1>{{$attrs.b}}</h1>
<!-- 多层传值: 代表这个组件内只传递数据,不接收数据,也不监听事件,它让它的父组件去监听,接收
$attrs:接收父组件传的所有属性
$listeners:将要触发的监听器让父组件去绑定-->
<Cox v-bind="$attrs" v-on="$listeners"></Cox>
</div>
</template>
<script>
import Cox from "@/components/Cox.vue"
export default {
// props:["b"],
components:{
Cox
}
}
</script>
<style>
.box{
width:200px;
height: 200px;
background-color: rgb(155, 20, 150);
margin: 20px;
}
</style>
孙组件:
<template>
<div class="cox">
<h3>{{b}}</h3>
<button @click="change2">change2</button>
</div>
</template>
<script>
export default {
//接收爷爷组件传来的值
props:["b"],
methods:{
change2(){
this.$emit("x","cox修改了数据")
}
}
}
</script>
<style>
.cox{
width: 100px;
height: 100px;
background-color: bisque;
margin: 10px;
}
</style>