..
This commit is contained in:
@@ -1,17 +1,88 @@
|
||||
const styleUtil = {
|
||||
// 为元素及其所有子元素添加scoped属性
|
||||
addScopedAttribute(el, scopedId) {
|
||||
if (el && el.setAttribute) {
|
||||
el.setAttribute(scopedId, '')
|
||||
|
||||
// 递归处理所有子元素
|
||||
const children = el.children || el.childNodes
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
styleUtil.addScopedAttribute(children[i], scopedId)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 移除元素及其所有子元素的scoped属性
|
||||
removeScopedAttribute(el, scopedId) {
|
||||
if (el && el.removeAttribute) {
|
||||
el.removeAttribute(scopedId)
|
||||
|
||||
// 递归处理所有子元素
|
||||
const children = el.children || el.childNodes
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
styleUtil.removeScopedAttribute(children[i], scopedId)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scopeCss(css, scopedId) {
|
||||
// 处理CSS规则,为每个选择器添加[scopedId]
|
||||
const processedCss = css.replace(/([^{]+){/g, (match, selectors) => {
|
||||
return selectors.split(',')
|
||||
.map(selector => {
|
||||
// 处理深度选择器 >>> 和 /deep/
|
||||
if (selector.includes('>>>') || selector.includes('/deep/')) {
|
||||
return selector.replace(/(\s*)(>>>|\/deep\/)(\s*)/g,
|
||||
`$1[${scopedId}] $3`)
|
||||
}
|
||||
|
||||
// 普通选择器
|
||||
return `${selector.trim()}[${scopedId}]`
|
||||
})
|
||||
.join(',') + '{'
|
||||
})
|
||||
|
||||
return processedCss
|
||||
}
|
||||
}
|
||||
|
||||
Vue.mixin({
|
||||
mounted() {
|
||||
if (this.$options.style) {
|
||||
const styleId = `style-${this._uid}`
|
||||
const style = document.createElement("style")
|
||||
style.id = styleId
|
||||
|
||||
// 生成唯一属性
|
||||
const scopedId = `data-v-${this._uid}`
|
||||
|
||||
// this.$el.setAttribute(scopedId, '')
|
||||
|
||||
// 为组件内所有元素添加唯一属性
|
||||
styleUtil.addScopedAttribute(this.$el, scopedId)
|
||||
|
||||
//支持函数和字符串
|
||||
const css = typeof this.$options.style === "function" ? this.$options.style.call(this) : this.$options.style
|
||||
let css = typeof this.$options.style === "function" ? this.$options.style.call(this) : this.$options.style
|
||||
|
||||
// 为每条规则添加属性选择器
|
||||
css = styleUtil.scopeCss(css, scopedId)
|
||||
|
||||
style.textContent = css
|
||||
document.head.appendChild(style)
|
||||
|
||||
// 保存scopedId以便销毁时使用
|
||||
this._scopedId = scopedId
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
beforeDestroy() {
|
||||
if (this._scopedId && this.$el) {
|
||||
// 移除所有元素的scoped属性
|
||||
styleUtil.removeScopedAttribute(this.$el, this._scopedId)
|
||||
}
|
||||
|
||||
if (this.$options.style) {
|
||||
const styleId = `style-${this._uid}`
|
||||
const style = document.getElementById(styleId)
|
||||
|
||||
Reference in New Issue
Block a user