大家好,今天这篇文章由我们的金牌导师uncle13提供。
当在 <style>
标签上使用 scoped
属性时,Vue 会为当前组件的每个元素添加一个唯一的 data-v-xxxxxx
属性,并将样式规则中的选择器修改为包含该属性的形式。
在编译 .vue
文件时,Vue 的编译器会处理 <style>
标签,具体步骤如下:
postcss
解析样式,生成 AST(抽象语法树)。[data-v-xxxxxx]
属性选择器。xxxxxx
是一个基于组件文件路径和内容的哈希值,确保唯一性。在运行时,Vue 会为组件的根元素和所有子元素添加 data-v-xxxxxx
属性。
::v-deep
或Vue 2中的/deep/
、>>>
)来“穿透”scoped限制。但需要注意的是,过度使用深度选择器可能会破坏样式的隔离性。以下是 Vue 源码中与 scoped
样式相关的关键部分:
src/compiler/style-processor.js
该文件负责处理 <style>
标签,主要逻辑如下:
export function addScopedIdToSelector (id, selector) {
return selector.replace(/^(\w+)/, `$1[data-v-${id}]`)
}
这个函数为选择器添加 data-v-xxxxxx
属性。
src/compiler/modules/style.js
该模块在编译模板时处理样式,主要逻辑如下:
function addScopedAttr (el, id) {
el.attrsMap['data-v-' + id] = ''
el.attrsList.push({ name: 'data-v-' + id, value: '' })
}
这个函数为元素添加 data-v-xxxxxx
属性。
src/platforms/web/runtime/modules/attrs.js
该模块在运行时处理元素属性,主要逻辑如下:
function updateAttrs (oldVnode, vnode) {
const el = vnode.elm
const oldAttrs = oldVnode.data.attrs || {}
const attrs = vnode.data.attrs || {}
for (let key in attrs) {
if (attrs[key] !== oldAttrs[key]) {
el.setAttribute(key, attrs[key])
}
}
}
这个函数在更新元素属性时,确保 data-v-xxxxxx
属性被正确应用。
假设有以下组件:
<template>
<div class="example">Hello World</div>
</template>
<style scoped>
.example {
color: red;
}
</style>
编译后生成的样式和模板如下:
<div class="example" data-v-f3f3eg9>Hello World</div>
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
最后
还没有使用过我们刷题网站(https://fe.ecool.fun/)或者刷题小程序的同学,如果近期准备或者正在找工作,千万不要错过,题库主打题全和更新快哦~。
有会员购买、辅导咨询的小伙伴,可以通过下面的二维码,联系我们的小助手。