返回

Vue3中的$attrs的变化与inheritAttrs的使用

前端

Vue3 中 $attrs 属性的转变和父组件属性渲染

Vue3 中 $attrs 的变化

在 Vue2 中,$attrs 用于将父组件属性直接渲染到根节点上,方便子组件访问父组件属性。然而,在 Vue3 中,$attrs 的作用有所改变,它现在仅负责将父组件属性传递给子组件,不再直接渲染到根节点。

性能优化

Vue3 中 $attrs 这一转变主要是出于性能优化考虑。在 Vue2 中,$attrs 依赖于虚拟 DOM 节点,会对性能产生一定影响。而 Vue3 中的 $attrs 直接传递属性,取消了虚拟 DOM 节点的使用,从而提升了性能。

在指定节点渲染父组件属性

若要将父组件属性渲染到指定节点,Vue3 提供了 inheritAttrs 属性。inheritAttrs 用于将父组件属性传递给子组件并渲染到指定节点。

代码示例

<!-- 父组件 -->
<template>
  <child-component title="Hello Vue3" />
</template>

<script>
export default {
  components: { ChildComponent }
};
</script>
<!-- 子组件 -->
<template>
  <div inheritAttrs>
    {{ attrs.title }}
  </div>
</template>

<script>
export default {};
</script>

通过 inheritAttrstitle 属性从父组件传递到子组件,并渲染到 <div> 元素中。

根节点和指定节点均不渲染问题

使用 inheritAttrs 时,可能会出现根节点和指定节点都不渲染的问题。这是因为 inheritAttrs 将父组件属性传递到子组件,而子组件的根节点正是父组件的指定节点。因此,若属性传递给了子组件,那么父组件根节点和子组件指定节点都会被渲染。

slot 插槽解决方案

为解决上述问题,可在子组件中使用 slot 插槽,用于将父组件属性渲染到指定节点。

代码示例

<!-- 父组件 -->
<template>
  <child-component>
    <template v-slot:title>
      Hello Vue3
    </template>
  </child-component>
</template>

<script>
export default {
  components: { ChildComponent }
};
</script>
<!-- 子组件 -->
<template>
  <div>
    <slot name="title"></slot>
  </div>
</template>

<script>
export default {};
</script>

slot 插槽指定了在子组件中渲染父组件属性的位置,解决了根节点和指定节点均不渲染的问题。

总结

在 Vue3 中,$attrs 属性发生了变化,仅用于传递父组件属性,不再直接渲染到根节点。若要将父组件属性渲染到指定节点,可以使用 inheritAttrs 属性或 slot 插槽。

常见问题解答

  1. $attrs 在 Vue2 和 Vue3 中有什么不同?
    在 Vue2 中,$attrs 可直接渲染到根节点,而在 Vue3 中,它仅传递属性。

  2. 如何使用 inheritAttrs 将父组件属性渲染到指定节点?
    inheritAttrs 添加到需要渲染属性的子组件元素上。

  3. 为什么使用 inheritAttrs 时,根节点和指定节点都可能不渲染?
    这是因为 inheritAttrs 会将父组件属性传递到子组件,而子组件根节点正是父组件的指定节点。

  4. 如何解决根节点和指定节点均不渲染的问题?
    可以使用 slot 插槽来指定在子组件中渲染父组件属性的位置。

  5. $attrs$listeners 有什么区别?
    $attrs 用于传递父组件属性,而 $listeners 用于传递事件侦听器。