Vue——组件传值3:多层传值($listeners & $attrs)

915 阅读1分钟

多层传值:

在不用状态管理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)

案例:

image.png

父组件:

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