..
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({
|
Vue.mixin({
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.$options.style) {
|
if (this.$options.style) {
|
||||||
const styleId = `style-${this._uid}`
|
const styleId = `style-${this._uid}`
|
||||||
const style = document.createElement("style")
|
const style = document.createElement("style")
|
||||||
style.id = styleId
|
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
|
style.textContent = css
|
||||||
document.head.appendChild(style)
|
document.head.appendChild(style)
|
||||||
|
|
||||||
|
// 保存scopedId以便销毁时使用
|
||||||
|
this._scopedId = scopedId
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
if (this._scopedId && this.$el) {
|
||||||
|
// 移除所有元素的scoped属性
|
||||||
|
styleUtil.removeScopedAttribute(this.$el, this._scopedId)
|
||||||
|
}
|
||||||
|
|
||||||
if (this.$options.style) {
|
if (this.$options.style) {
|
||||||
const styleId = `style-${this._uid}`
|
const styleId = `style-${this._uid}`
|
||||||
const style = document.getElementById(styleId)
|
const style = document.getElementById(styleId)
|
||||||
|
|||||||
Reference in New Issue
Block a user