Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vue] scope 是怎么做的样式隔离的【热度: 126】 #843

Open
yanlele opened this issue Aug 18, 2024 · 0 comments
Open

[vue] scope 是怎么做的样式隔离的【热度: 126】 #843

yanlele opened this issue Aug 18, 2024 · 0 comments
Labels
web框架 web 框架相关知识 京东 公司标签
Milestone

Comments

@yanlele
Copy link
Member

yanlele commented Aug 18, 2024

关键词:vue 样式个例

Vue 中的样式隔离是通过 Vue 单文件组件(Single File Components,简称 SFC)的 <style> 标签中的 scoped 属性实现的。当你在一个 Vue 组件的 <style> 标签上添加 scoped 属性时,Vue 会自动将该样式限定在当前组件的范围内,从而防止样式冲突和不必要的样式泄漏。

实现原理

Vue 在编译带有 scoped 属性的 <style> 标签时,会按照以下步骤处理样式隔离:

  1. 生成唯一的作用域 ID:Vue 为每个带有 scoped 属性的组件生成一个唯一的作用域 ID(如 data-v-f3f3eg9)。这个 ID 是随机的,确保每个组件的作用域 ID 是独一无二的。

  2. 添加作用域 ID 到模板元素:Vue 会在编译组件模板的过程中,将这个作用域 ID 作为自定义属性添加到组件模板的所有元素上。例如,如果作用域 ID 是 data-v-f3f3eg9,那么在该组件模板的所有元素上都会添加一个属性 data-v-f3f3eg9

  3. 修改 CSS 选择器:对于组件内部的每个 CSS 规则,Vue 会自动转换其选择器,使其仅匹配带有对应作用域 ID 的元素。这是通过在 CSS 选择器的末尾添加相应的作用域 ID 属性选择器来实现的。例如,如果 CSS 规则是 .button { color: red; },并且作用域 ID 是 data-v-f3f3eg9,那么该规则会被转换成 .button[data-v-f3f3eg9] { color: red; }

示例

假设有如下 Vue 单文件组件:

<template>
  <button class="btn">Click Me</button>
</template>

<style scoped>
.btn {
  background-color: red;
}
</style>

编译后,CSS 规则会变成类似于这样(注意:实际的作用域 ID 是随机生成的):

.btn[data-v-f3f3eg9] {
  background-color: red;
}

并且模板里的 <button> 元素会被编译为类似这样:

<button class="btn" data-v-f3f3eg9>Click Me</button>

这样,.btn 样式规则只会应用到当前组件中的 <button> 元素上,而不会影响到其他组件中的同类元素,实现了样式隔离。

注意事项

  • 由于样式隔离是通过属性选择器和自定义属性实现的,因此这种方法的性能可能会略低于全局样式规则。
  • scoped 样式不能影响子组件,仅限于当前的组件。如果需要影响子组件,则需要使用深度选择器(>>>/deep/)。
  • 其他 Web 组件技术如 Shadow DOM 也可以提供样式隔离的功能,但 Vue 选择了这种不需要 polyfill、兼容性更好的实现方式。
@yanlele yanlele added web框架 web 框架相关知识 京东 公司标签 labels Aug 18, 2024
@yanlele yanlele added this to the milestone Aug 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
web框架 web 框架相关知识 京东 公司标签
Projects
None yet
Development

No branches or pull requests

1 participant