Skip to content

扩展

透传 Attributes

Attributes 继承

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

一个简单的例子:

html
<MyComponent class="baz boo" />
js
// MyComponent 的模板
<div class="foo bar">...</div>

最终渲染结果:

html
<div class="foo bar baz boo">...</div>

对 class 和 style 的合并

如果一个子组件的根元素已经有了 class 或 style attribute,它会和从父组件上继承的值合并。

v-on 监听器继承(同上)

深层组件继承

有些情况下一个组件会在根节点上渲染另一个组件

html
<!-- <MyButton/> 的模板,只是渲染另一个组件 -->
<BaseButton />

此时 <MyButton> 接收的透传 attribute 会直接继续传给 <BaseButton>

注意

1、透传的 attribute 不会包含 <MyButton> 上声明过的 props 或是针对 emits 声明事件的 v-on 侦听函数,换句话说,声明过的 props 和侦听函数被 <MyButton>“消费”了。 2、透传的 attribute 若符合声明,也可以作为 props 传入 <BaseButton>

禁用 Attributes 继承

如果你不想要一个组件自动地继承 attribute,你可以在组件选项中设置 inheritAttrs: false

js
<script setup>
defineOptions({
  inheritAttrs: false
})
// ...setup 逻辑
</script>

透传进来的 attribute 可以在模板的表达式中直接用 $attrs 访问到

html
<span>Fallthrough attribute: {{ $attrs }}</span>

这个 $attrs 对象包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等

注意

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

多根节点的 Attributes 继承

使用$attrs显示绑定(如果 $attrs 没有被显式绑定,将会抛出一个运行时警告。) 在 JavaScript 中访问透传 Attributes

js
<script setup>
import { useAttrs } from 'vue'

const attrs = useAttrs()
</script>

注意

透传 attribute不是响应式

key

  • key 这个特殊的 attribute 主要作为 Vue 的虚拟 DOM 算法提示,在比较新旧节点列表时用于识别 vnode。
  • 在没有 key 的情况下,Vue 将使用一种最小化元素移动的算法,并尽可能地就地更新/复用相同类型的元素。如果传了 key,则将根据 key 的变化顺序来重新排列元素,并且将始终移除/销毁 key 已经不存在的元素。
  • 同一个父元素下的子元素必须具有唯一的 key。重复的 key 将会导致渲染异常。
  • 结合v-for使用
html
<ul>
  <li v-for="item in items" :key="item.id">...</li>
</ul>

推荐在任何可行的时候为 v-for 提供一个 key attribute,除非所迭代的 DOM 内容非常简单 (例如:不包含组件或有状态的 DOM 元素),或者你想有意采用默认行为来提高性能。

思考

html
<!-- 是否会触发过渡效果 -->
<transition>
  <span :key="text">{{ text }}</span>
</transition>

ref

  • 使用选项式 API,引用将被注册在组件的 this.$refs 对象里
  • 使用组合式 API,引用将存储在与名字匹配的 ref 里
  • ref 注册时机的重要说明:因为 ref 本身是作为渲染函数的结果来创建的,必须等待组件挂载后才能对它进行访问。

is

用于绑定动态组件。

html
<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>

在上面的例子中,被传给 :is 的值可以是以下几种:

  • 被注册的组件名
  • 导入的组件对象

单文件组件 CSS 功能

单文件组件 CSS 功能

Released Under The MIT License.