标准答案

  1. scoped CSS 会在编译时给当前组件模板节点加上类似 data-v-xxxx 的属性,并把样式选择器也改写成带这个属性的形式。
  2. 它能减少当前组件样式泄漏到其它组件,但不是 Shadow DOM,仍然会受到全局样式、继承属性和子组件根节点影响。
  3. :deep() 用来穿透到子组件内部元素,适合覆盖组件库内部样式,但要控制范围。
  4. :slotted() 用来选择插槽传入内容,适合组件要约束 slot 内容外观的场景。
  5. :global() 用来在 scoped 块里声明全局样式,应该少用,并且命名要避免污染。

题目解析

scoped 的本质是选择器改写,不是运行时样式隔离。

deep 选择器越宽,越容易打破组件封装。二次封装组件库时应优先用组件提供的 class、变量或 API。

插槽内容属于父组件作用域。要影响插槽内容时,普通 scoped 选择器不一定能命中,需要理解 slotted 的边界。

代码示例

下面展示 scoped、deep 和 global 的典型写法。

Vue
<template>
  <section class="panel">
    <ThirdPartyTable />
  </section>
</template>

<style scoped>
.panel {
  padding: 16px;
}

:deep(.third-party-table__header) {
  font-weight: 600;
}

:global(.app-lock-scroll) {
  overflow: hidden;
}
</style>

常见误区

  • 以为 scoped CSS 能完全隔离样式,不会受到任何全局样式影响。
  • 大量使用 :deep() 覆盖组件库内部结构,组件库升级后样式容易失效。
  • 在 scoped 里随意写 :global(),导致全站样式污染。

作者信息