Vue3中的透传Attributes / $attrs:简化组件开发的利器

前言

Vue3推出了一系列新功能和改进。使用下来后,其中一个很实用的新特性就是透传 Attributes(透传属性)。本文将介绍 Vue3中的透传 Attributes,并提结合代码示例来展示它在实际项目中的使用。

一、什么是透传 Attributes?

在 Vue 中,父组件可以通过属性(Props)向子组件传递数据,以控制子组件的行为和外观。然而,在某些情况下,我们希望将父组件的属性直接传递给子组件内部的 HTML 标签或自定义组件

以前,我们需要手动将这些属性逐层传递下去,但现在 Vue 3 引入了透传 Attributes 来简化这个过程。

透传 Attributes 允许在组件中自动将父组件的未声明 Props 直接传递给子组件的根元素或另一个指定元素。这意味着你可以更方便地在子组件中访问到父组件的属性,而无需手动一层层传递。

Vue3中文官网解释

二、如何使用透传 Attributes?

1. 具体使用

  • 父组件:直接传属性
<template>
  <div>
    <ChildComponent name="John Doe" age="25" />
  </div>
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';
</script>
  • 子组件:使用 $attrs 或 useAttrs() 接收属性
<template>
  <div>
    <h2>{
   
   { name }}</h2>
    <p>{
   
   { $attrs.age }}</p>
    <!-- 在模板的表达式中直接用 $attrs 访问到 -->
    <p>{
   
   { attrs.age }}</p>
  </div>
</template>

<script setup>
  // 在js里 使用 useAttrs() API 来访问到
  import { useAttrs } from 'vue'

  defineProps({
    name: String
  })

  const attrs = useAttrs()
  console.log(attrs)
</script>

打印:

在上述示例中,我们有一个父组件,在模板中引入了一个子组件 <ChildComponent>。父组件给子组件传递了两个属性:nameage

在子组件中,我们使用了 props 对象来声明 name 属性,而没有声明 age 属性。这时,age 属性就会被视为透传 Attributes,打印的内容中和渲染的p标签里,包含了父组件传递的未声明 Props age 的值。

通过透传 Attributes,我们可以轻松地在子组件中访问到父组件的属性,而不需要手动声明和传递。

2. 注意事项

当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。多个根节点的组件没有自动 attribute 透传行为。如果 $attrs 没有被显式绑定,或者没有被使用,将会抛出一个运行时警告。

把上面的子组件改一下,多一个div根节点:

<template>
  <div>
    <h2>{
   
   { name }}</h2>
  </div>
  // 多了一个根元素
  <div></div>
</template>

<script setup>
  defineProps({
    name: String
  })
</script>

此时报错表示:vueVue 不知道要将 attribute 透传到哪里。

解决办法:如果 $attrs 被显式绑定 或者 使用,或者 两者同时出现,则不会有警告。

<template>
  <!-- 显示绑定 -->
  <div v-bind="$attrs">
    <h2>{
   
   { name }}</h2>
  </div>
  <div>
    <!-- 使用 -->
    <p>{
   
   { $attrs.age }}</p>
  </div>
</template>

<script setup>
  defineProps({
    name: String
  })
</script>

可能这里会有人疑惑,既然显示绑定了上面的div,下面的div依旧可以通过 $attrs 使用属性,那显示绑定的作用是什么?不是多此一举了吗?

其实不然。让我们把父组件改一下,添加一个id属性,子组件不做更改:

<template>
  <div>
    <ChildComponent id="custom-layout" name="John Doe" :age="25" />
  </div>
</template>

<script setup>
  import ChildComponent from './ChildComponent.vue'
</script>

这时就可以看到,父组件传递下来的id属性,自动添加到了使用 v-bind 显示绑定的元素上了。

三、透传 Attributes 的实际应用

1. 外部库集成

当我们在使用外部库或第三方组件时,可能需要将一些属性传递给这些组件以进行配置或自定义。透传 Attributes 可以很方便地将父组件的属性直接传递给外部库或第三方组件。

<template>
  <div>
    <ThirdPartyComponent v-bind="$attrs" />
  </div>
</template>

<script setup>
import ThirdPartyComponent from 'third-party-library';
</script>

在上述示例中,我们通过 $attrs 函数来获取父组件的所有未声明 Props,并将其直接传递给一个名为 ThirdPartyComponent 的第三方组件。

2. 高阶组件

透传 Attributes 还可以用于高阶组件(Higher-Order Components)的开发。高阶组件是一个接收一些额外属性,并将这些属性传递给内部子组件的组件。

<template>
  <div>
    <WrappedComponent v-bind="$attrs" />
  </div>
</template>

<script setup>
import WrappedComponent from './WrappedComponent.vue';
</script>

在上述示例中,我们创建了一个高阶组件,并通过 attrs 函数来获取父组件的所有未声明 Props,并将其直接传递给子组件 WrappedComponent

3. 动态组件

使用动态组件时,透传 Attributes 可以让父组件的属性传递到被动态渲染的组件中。

<template>
  <div>
    <component :is="dynamicComponent" v-bind="$attrs" />
  </div>
</template>

<script setup>
const dynamicComponent = 'ChildComponent';
</script>

在上述示例中,我们使用了动态组件来根据条件渲染不同的组件。通过 :isv-bind,我们可以将父组件的所有未声明 Props 透传给被动态渲染的组件。

猜你喜欢

转载自blog.csdn.net/weixin_42373175/article/details/131794756
今日推荐