本地demo样式显示正常,将demo移植VUE项目CSS样式不起作用问题排查------使用:deep(class/id)解决
前几天在本地单独写了个demo页面调试显示效果,效果正常,达到预期效果,于是将demo移植到已有的大屏项目中。
但是奇怪的问题出现了,移植大屏后,原有的demo页面CSS样式不起作用,但是DOM结构和数据都渲染出来了。
排查了很久,有考虑内部demo页面的class/id样式名称等是否和大屏CSS文件内其他名称冲突问题、也有考虑CSS加载和DOM加载的先后顺序问题,但都排除了。
这里需要特别说明的背景:css样式显示异常部分是我通过js动态生成的html结构,然后html结构里注明了使用的class和id。
查了好久,通过浏览器调试模式,发现vue页面在渲染出div结构后,在class名称后会出现:data-v-xxxx格式的字符串:

查了下原因是因为vue在引入CSS时用了scoped作用域的问题:

Scoped样式的工作原理
-
Vue/React的scoped特性:
-
会为组件内所有元素添加唯一属性标识(如
data-v-5d6e8c3) -
转换CSS选择器为
.card[data-v-5d6e8c3]这样的形式
-
-
与动态生成DOM的冲突:
-
JS动态生成的DOM元素不会自动获得scoped属性
-
导致CSS选择器无法匹配动态生成的元素
-
解决办法:在受影响的css样式class/id名称前加::deep
即:格式类似:deep(class/id名):
1 :deep(.card-header) { 2 display: flex; 3 justify-content: space-between; 4 align-items: center; 5 /* margin-bottom: 15px; */ 6 margin-bottom: 3%; 7 /* 底部加一条横线 */ 8 border-bottom: 1px solid rgba(255, 255, 255, 0.2); 9 /* padding-bottom: 5px; */ 10 padding-bottom: 1%; 11 /* border:1px solid red; */ 12 }
原因:
:deep() 是 Vue 3 的 Scoped CSS 中引入的一个特殊选择器,专门用于解决 Scoped 样式与动态生成 DOM 的匹配问题。
:deep() 的核心作用?
-
穿透 Scoped 限制:
-
允许样式穿透到子组件或动态生成的 DOM 元素
-
不会自动添加
data-v-xxxx属性到选择器
-
-
解决当前的问题:
-
让 Scoped 样式可以作用于 JS 动态生成的 DOM 结构
-
无需手动添加
data-v属性
-
何时应该使用 :deep()?
-
动态生成的 DOM 结构:
-
像您这样用 JS 生成的 HTML 模板
-
-
第三方组件样式覆盖:
-
需要修改子组件内部样式时
-
-
嵌套较深的结构:
-
需要影响多层嵌套的子元素时
-

浙公网安备 33010602011771号