「踩坑记录」在 Vue 中处理多根节点和样式传递问题

发布于 2024-03-05  33 次阅读


问题一

问题描述

当子组件有多个根节点时,父组件在子组件上设置的属性将失效,因为无法确定将属性设置在哪个根节点上。

解决方法

使用 $attrs 传递类和样式:

在子组件中,你可以使用 v-bind="$attrs" 显式地将父组件传递的所有属性(包括类和样式)绑定到子组件的根元素上。这种方式确保了所有从父组件传递的额外属性都能被正确应用。

<!-- 子组件 -->
<template>
  <div v-bind="$attrs">
    <!-- 子组件内容 -->
  </div>
</template>

问题二

问题描述

原本是可以在父组件的<style scoped></style>中定义将要传给子组件的class的样式的我平时不怎么使用这种写法,但同事这样用了,也确实可以),但是通过问题一的解决方法将类名传递给具有多个根节点的子组件的某个根节点后,虽然类名可以被正确传递,但是样式不会被作用到子组件的该根节点上。(因为scoped限制了作用域)

解决方案

处于 scoped 样式中的选择器如果想要做更“深度”的选择,也即:影响到子组件,可以使用 :deep()这个伪类:

<style scoped>
.a :deep(.b) {
  /* ... */
}
</style>

详见深度选择器

这种方法允许你在父组件中定义的样式穿透到子组件中,即使样式是 scoped 的。

结论

在 Vue 中,特别是在使用具有多个根节点的组件和 scoped 样式时,正确地传递样式和类是一项挑战。通过使用 v-bind="$attrs" 和深度选择器,我们可以有效地解决这些问题,确保样式正确应用,同时保持组件间的样式隔离。正确地使用这些技术可以让你的 Vue 应用更加模块化和可维护。


A Student on the way to full stack of Web3.