vue透传 Attributes

Attributes 继承​

在此之前,先来弥补一个小知识点,vue3支持多个根节点,vue2不支持,

<!--vue2: 错误的写法-->
 <template>
   <div></div>
   <div></div>
 </template>
 <!--vue3: 正确-->
 <template>
   <div></div>
   <div></div>
 </template>

“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。

当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。举例来说,假如我们有一个 MyButton 组件,它的模板长这样:

<!-- <MyButton> 的模板 -->
<button>click me</button>

一个父组件使用了这个组件,并且传入了 class:

<MyButton class="large" />

最后渲染出的 DOM 结果是:

<button class="large">click me</button>
这里,MyButton 并没有将 class 声明为一个它所接受的 prop,所以 class 被视作透传 attribute,自动透传到了 MyButton的根元素上。

多个根节点

存在多个根节点的时候,并且还传递了透传 attributes,如果没有手动处理的话,是会存在警告的。

那么处理警告的方式两种:
禁用透传 attributes,设置 inheritAttrs 为 false(后面再说)。手动处理,具体绑定在哪一个根节点。

<!--son子组件-->
 <template>
   <div class="own" :class="$attrs['class']">son组件1</div>
   <div class="own">son组件2</div>
 </template>

这样警告也会消失,并且把透传 attributes 绑定在了第一个根节点上。这里的$attrs是一个对象,需要具体指明某个属性。
最后渲染的结果

 <div class="own abc">son组件1</div>
 <div class="own">son组件2</div>

v-on 监听器继承

透传 attributes 之事件绑定 上面只是针对样式进行了透传,那么事件的话,又会是怎么样的呢?
先说结论吧,表现形式跟样式绑定是基本一样的。

<!--子组件Son-->
 <script setup lang="ts">
 const btn1 = () => {
   console.log("子组件的点击事件");
 };
 </script>
 <template>
   <button @click="btn1">点击</button>
 </template>

现在子组件的根节点是一个 button 标签,并且上面绑定了一个点击事件。

<!--父组件使用-->
 <script setup lang="ts">
 import Son from "./Son.vue";
 const btn = () => {
   console.log("父组件的点击事件");
 };
 </script>
 <template>
   <Son @click="btn" />
 </template>

父组件调用,也传递了一个透传的事件过来。当点击按钮:
image

现,子组件的事件被触发了,父组件传递过来的事件也被触发了,顺序为先子后父。
透传的 attributes 基本说完了,接下来就看看几个特殊部分吧。

禁用透传attributes

设置 inheritAttrs:false,就禁止使用了自动绑定,可以消除前面所说的警告;然后就可以自由的绑定 $attrs, 该对象就包含了传递过来的透传 attributes。

<!--如果是setup写法,就需要单独添加一个script标签,暴露一个配置对象-->
 <script lang="ts">
 export default {
   inheritAttrs: false, // 禁用
 };
 </script>
 <script setup lang="ts">
 const btn1 = () => {
   console.log("子组件的点击事件");
 };
 </script>
 <template>
   <button @click="btn1">点击</button>
 </template>

需要注意的是:
和 props 有所不同,透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像 foo-bar 这样的一个 attribute 需要通过 $attrs['foo-bar'] 来访问。像 @click 这样的一个 v-on 事件监听器将在此对象下被暴露为一个函数 $attrs.onClick。

posted @ 2023-06-27 22:00  yunChuans  阅读(107)  评论(0编辑  收藏  举报