专业的编程技术博客社区

网站首页 > 博客文章 正文

Vue 3 进阶用法:透传特性(vue3 样式穿透)

baijin 2024-10-27 08:13:45 博客文章 16 ℃ 0 评论

一、什么是透传特性?

如果子组件声明了 1 个属性,但是父组件传过来 2 个属性,Vue 3 如何处理多出来的这个属性?

写个例子测试一下。

打开浏览器开发者工具,会发现 bar 属性被转换为 DOM 属性,附在了子组件的根结点。

假如多余的属性不是字符串类型,而是函数类型:

会先转换为字符串,然后放在 DOM 属性中。

像 bar 这种,没有在子组件中声明,却被父组件硬塞的属性,Vue 用一个专有名词描述:透传特性(Fallthrough Attributes)。

二、最常见的透传特性

class, id 和 style 是三个最常见的透传特性。用代码测试一下三者的透传规则:

在开发者工具中可以看到,class 和 style 会同时保留父组件和子组件的值,对于父子组件的同名 style,父组件的优先级更高。id 也是父组件的优先级高。

如果子组件的根结点不止 1 个,这 3 个值也会同样透传到所有根结点吗?

修改子组件为 2 个根结点,测试一下:

可以看到,父组件的值并未透传到子组件的 DOM 属性。

而且,浏览器开发者工具有一个警告信息:

小结一下:

  1. 如果子组件只有一个根节点,默认情况下父组件会把透传特性硬塞给他。
  2. 如果子组件有多个根结点,父组件不会硬塞,因为不知道塞给哪位。

三、禁止特性自动继承

子组件有多个根节点时,浏览器的警告信息实在烦人,有没有办法取消它?有一个办法,就是禁用特性自动继承。

在 Vue 3.3+ 中,可以在 <script setup> 使用 defineOptions() 宏,传入 inheritAttrs: false 即可禁用特性自动继承。

注意,当子组件只有一个根节点时,如果禁用特性的自动继承,父组件的 class, id, style 也同样不会自动透传到子组件的根结点。

四、获取透传特性的值

在子组件的 <template> 块中,使用 $attrs 获取透传特性的值。

在浏览器开发者工具,可以看到 DOM 树中 $attrs 对应的值:

可以在模板中使用点语法(如 $attrs.bar )或方括号语法(如 $attrs['foo-baz'])访问其中的具体键值。

注意,中横线分隔属性名(如例子中的 "foo-baz")保留原样,并不会被 Vue 自动转换为驼峰风格

在子组件的 <script setup> 块中,使用 useAttrs() API 访问透传属性。

打印输出的值如下:

五、回调函数的透传

上面的例子仅仅展示了属性的透传,未在子组件声明的回调函数和属性一样,同样也会出现在 $attrs 中。

输出结果如下:

参考资料

  • Fallthrough Attributes,https://vuejs.org/guide/components/attrs.html

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表