scoped原理就是穿透组件,为组件下的标签绑定data-v-hash来实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title></title>
<style>
#app {
color: white;
}
.childB {
background-color: #07c160;
}
.childCCC {
background-color: #ff9e55;
}
</style>
</head>
<body>
<div id="app" style="background: #2C93FF">
<div>
子组件A
</div>
<div class="childB">
子组件B
<p>孙子组件BB</p>
</div>
<div>
子组件C
<div>孙子组件CC
<div class="childCCC">从孙组件CCC</div>
</div>
</div>
</div>
<script>
function createHash(hashLength) {
if (!hashLength || typeof (Number(hashLength)) != 'number') {
return;
}
const ar = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
const hs = [];
const hl = Number(hashLength);
const al = ar.length;
for (let i = 0; i < hl; i++) {
hs.push(ar[Math.floor(Math.random() * al)]);
}
return hs.join('');
}
/**
* 递归整个DOM树,添加上data-v-hash的属性
*/
function recursive(el) {
if (el.children && el.children.length > 0) {
for (let i = 0; i < el.children.length; i++) {
const childrenNode = el.children[i]
setHashAttribute(childrenNode)
recursive(childrenNode)
}
}
}
function setHashAttribute(el) {
el.setAttribute('data-v-' + hash, "");
}
/**
* 将data-v-hash属性添加到css
* @param cssForElment cssSheet中的每个CSS项目
* @param hash
*/
function _SetCSSStyleValue(cssForElment, hash) {
if (cssForElment.selectorText) {
cssForElment.selectorText = cssForElment.selectorText + `[data-v-${hash}]`
}
}
const el = document.getElementById('app')
const hash = createHash(7);
//拿到style表,找到里面选择器的style项目 重置他们的选择器 这样就是针对.类名 [data-v-hash]的形式
for (let j = 0; j < document.styleSheets.length; j++) {
let cSSStyleList = []
if (document.styleSheets[j].cssRules)
cSSStyleList = document.styleSheets[j].cssRules
else cSSStyleList = document.styleSheets[j].rules;
for (let k = 0; k < cSSStyleList.length; k++) {
_SetCSSStyleValue(cSSStyleList[k], hash)
}
}
recursive(el)
setHashAttribute(el)
</script>
</body>
</html>
效果图