父组件与子组件的属性透传:VOA模式

透传是vue中一种特性,官方的解释是:“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 propsemits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 classstyleid

这句话解释过来就是一些不被prop定义的属性直接添加到子组件上的时候,子组件是可以获取到的,只不过获取的方式是通过方法获取的,下面我们展开说一下

规则 

父组件在使用子组件的时候,如何“透传属性和事件”给子组件呢?

透传属性和事件并没有在子组件中用props和emits声明
透传属性和事件最常见的如@click和class、id、style 
当子组件只有一个根元素时,透传属性和事件会自动添加到该根元素上;如果根元素已有class或style属性,它会自动合并                       

1、透传的属性只会直接传给单根节点的组件,如果子组件不是一个根节点,那么透传属性会直接失效,并且警告 

举列:

我有一个父组件App.vue

<template>
  <div>
    <!--在子组件中添加两个属性 id和class,如果子组件ChildModule只存在一个单根节点的元素,并且ChildModule中没有用props来接收id和class,那么这个di和class,就会传递给Navbar节点的根节点-->
    <ChildModule id="box" class="aaa"></ChildModule>
  </div>
</template>
<script>
import ChildModule from "./components/ChildModule.vue" //导入ChildModule组件模板
export default{
  data(){
  },
  components:{
    ChildModule:ChildModule //注册局部子组件ChildModule:也可以写成ChildModule:ChildModule
  }
}
</script>

案列1:透传的属性只会直接传给单根节点的组件

子组件

<template>
    <!-- 此组件只有一个div的根节点(注意:<template></template>不是节点,它不会显示在界面上的) -->
    <!-- 所以从父组件传递过来的id,class,style就会被此根节点接收 -->
    <div>
       <button>提交</button>
    </div>
</template>

查看F12元素可以体现

案列2:如果子组件不是一个根节点,那么透传属性会直接失效,并且警告

如果子组件存在两个根组件的情况下则透传会被失效

<template>
    <!-- 注意:<template></template>不是节点,它不会显示在界面上的 -->
    <!-- 因为子组件不是一个根节点,它有两个根节点d,透传属性会直接失效,并且警告 -->
    <div> <!--根节点1-->
        <button>提交</button>
    </div>
    <div> </div><!--根节点2-->
</template>

查看F12元素可以体现

 案列3:子组件中用props接收的属性传透属性会直接失效

<template>
    <!-- 此组件只有一个div的根节点(注意:<template></template>不是节点,它不会显示在界面上的) -->
    <!-- 因为script中用props接收了class属性,但是没接收id属性,所以id属性会被透传到此根节点 -->
    <div> <!--根节点1-->
       <button>提交</button>
    </div>
</template>
<script>
export default{
props:["class"]

}
</script>

查看F12元素可以体现

案列4:透传过去的属性如果和子组件上的命名或属性重复了,会会以子组件本身的属性为主或追加

透传过去的属性如果和子组件上的命名重复了,会以子组件本身的属性为主(id)
透传过去的属性如果和子组件上的属性重复了,会直接添加到属性值的后面(style,class)

<template>
    <!-- 此组件只有一个div的根节点(注意:<template></template>不是节点,它不会显示在界面上的) -->
    <!-- 透传过去的属性如果和子组件上的命名重复了,会以子组件本身的属性为主 -->
    <!-- 透传过去的属性如果和子组件上的属性重复了,会直接添加到属性值的后面 -->
    <div id="wowo" class="bbb">
        <button>提交</button>
    </div>
</template>

查看F12元素可以体现

2、透传事件

案列

父组件

<template>
  <div>
    <!--在子组件中添加两个属性 id和class,如果子组件ChildModule只存在一个单根节点的元素,并且ChildModule中没有用props来接收id和class,那么这个di和class,就会传递给Navbar节点的根节点-->
    <ChildModule id="box" class="aaa" @click="handelClick()"></ChildModule>
  </div>
</template>
<script>
import ChildModule from "./components/ChildModule.vue" //导入ChildModule组件模板
export default{
  data(){
  },
  components:{
    ChildModule:ChildModule //注册局部子组件ChildModule:也可以写成ChildModule:ChildModule
  },
  methods:{
    handelClick(){
      console.log("1111")
    }
  }
}
</script>

 子组件

<template>
    <!-- 注意:<template></template>不是节点,它不会显示在界面上的 -->
    <!-- 因为子组件不是一个根节点,它有两个根节点d,透传属性会直接失效,并且警告 -->
    <div> <!--根节点1-->
        <button>提交</button>
    </div>
</template>

点击提交的时候,会发现打印出了: 22222,说明,父组件的handelClick事件也传递给了子组件的根节点。子组件根节点也就有了这个绑定事件。(其规则也是与透传属性是一样的)

3、禁止透传

父组件

<template>
  <div>
    <!--在子组件中添加两个属性 id和class,如果子组件ChildModule只存在一个单根节点的元素,并且ChildModule中没有用props来接收id和class,那么这个di和class,就会传递给Navbar节点的根节点-->
    <ChildModule id="box" class="aaa" @click="handelClick()"></ChildModule>
  </div>
</template>
<script>
import ChildModule from "./components/ChildModule.vue" //导入ChildModule组件模板
export default {
  data() {
    return {
    }
  },
  components: {
    ChildModule: ChildModule //注册局部子组件ChildModule:也可以写成ChildModule:ChildModule
  },
  methods: {
    handelClick() {
      console.log("1111")
    }
  }
}
</script>

添加 inheritAttrs:false可以禁止透传

子组件

<template>
    <!-- 此组件只有一个div的根节点(注意:<template></template>不是节点,它不会显示在界面上的) -->
    <!-- 透传过去的属性如果和子组件上的命名重复了,会以子组件本身的属性为主 -->
    <!-- 透传过去的属性如果和子组件上的属性重复了,会直接添加到属性值的后面 -->
    <div id="wowo" class="bbb" >
        <button>提交</button>
    </div>
</template>
<script>
export default{
    //禁止透传:在子组件中添加inheritAttrs为false,则父组件的属性和事件不会被透传到子组件
    //虽然指定了 inheritAttrs:false 但是子组件仍然可以通过 v-bind="$attrs"来得到负组件透传过来的属性和事件
    inheritAttrs:false,
}
</script>

虽然指定了 inheritAttrs:false 但是子组件仍然可以通过 v-bind="$attrs"来得到父组件透传过来的属性和事件

子组件

<template>
    <!-- 此组件只有一个div的根节点(注意:<template></template>不是节点,它不会显示在界面上的) -->
    <!-- 透传过去的属性如果和子组件上的命名重复了,会以子组件本身的属性为主 -->
    <!-- 透传过去的属性如果和子组件上的属性重复了,会直接添加到属性值的后面 -->
    <div id="wowo" class="bbb" >
        <button v-bind="$attrs">提交</button>
    </div>
</template>
<script>
export default{
    //禁止透传:在子组件中添加inheritAttrs为false,则父组件的属性和事件不会被透传到子组件
    //虽然指定了 inheritAttrs:false 但是子组件仍然可以通过 v-bind="$attrs"来得到负组件透传过来的属性和事件
    inheritAttrs:false,
}
</script>

查看F12元素可以体现(点击button可以发现button已经绑定了handelClick事件,打印了1111)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值