为什么vue∶deep、deep、>>>样式能穿透到子组件
点击关注公众号,“技术干货”及时达!
在scoped标记的style中,只要涉及三方组件,那deep符号会经常被使用,用来修改外部组件的样式。
小试牛刀不使用deep
要想修改三方组件样式,只能添加到scoped之外,弊端是污染了全局样式,后续可能出现样式冲突。
style lang="less"
.container {
.el-button {
background: #777;
}
}
使用 /deep/ deprecated
.container1 {
/deep/ .el-button {
background: #000;
}
}
使用 deprecated
.container2 .el-button {
background: #222;
}
当在vue3使用/deep/或者、::v-deep,console面板会打印警告信息:
the and /deep/ combinators have been deprecated. Use :deep() instead.
由于/deep/或者在less或者scss中存在兼容问题,所以不推荐使用了。
使用:deep
.container3 {
:deep(.el-button) {
background: #444;
}
}
那么问题来了,如果我按以下的方式嵌套deep,能生效吗?
.container4 {
:deep(.el-button) {
:deep(.el-icon) {
color: #f00;
}
}
}
源码解析/deep/或会被编译为什么
编译后的代码为:
.no-deep .container1[data-v-f5dea59b] .el-button { background: #000; }
源代码片段:
if (
n.type === 'combinator' &&
(n.value === '' || n.value === '/deep/')
) {
n.value = ' '
n.spaces.before = n.spaces.after = ''
warn(
`the and /deep/ combinators have been deprecated. ` +
`Use :deep() instead.`,
)
return false
}
当vue编译样式时,先将样式解析为AST对象,例如deep/ .el-button会被解析为Selector对象,/deep/ .el-button解析后生成的Selector包含的字段:
{ type: 'combinator', value: '/deep/' }
然后将n.value由/deep/替换为空。所以转换出来的结果,.el-button直接变为.container下的子样式。
:deep会被编译为什么?
编译后的代码:
.no-deep .container3[data-v-f5dea59b] .el-button { background: #444; }
源代码片段:
// .foo :v-deep(.bar) - .foo[xxxxxxx] .bar
let last: selectorParser.Selector['nodes'][0] = n
n.nodes[0].each(ss = {
selector.insertAfter(last, ss)
last = ss
})
// insert a space combinator before if it doesn't already have one
const prev = selector.at(selector.index(n) - 1)
if (!prev || !isSpaceCombinator(prev)) {
selector.insertAfter(
n,
selectorParser.combinator({
value: ' ',
}),
)
}
selector.removeChild(n)
还是以.container4 :deep(.el-button)为例,当解析到:deep符号式,selector快照为
image.pngparent为.container4 :deep(.el-button),当前selector的type正好为伪类标识pseudo,nodes节点包含一个.el-button。
经过递归遍历,生成的selector结构为.container4 :deep(.el-button).el-button,
最后一行代码selector.removeChild(n)会将:deep(.el-button)移出,所以输出的最终样式为.container4 .el-button。
如果样式为:deep(.el-button) { :deep(.el-icon) { color: #f00 } },当遍历.el-icon时找不到ancestor,所以直接将:deep(.el-icon)作为其icon时找不到ancestor,其结果为:
.no-deep .container4[data-v-f5dea59b] .el-button :deep(.el-icon) { color: #f00; }
因此,deep是不支持嵌套的。
结尾插个广告,麻烦各位大佬为小弟开源项目标个??,点点关注:
react-native-mapa[1], react native地图组件库mapboxgl-syncto-any[2],三维地图双屏联动参考资料[1]https://github.com/cnmapos/react-native-mapa: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fcnmapos%2Freact-native-mapa
[2]https://github.com/cnmapos/mapboxgl-syncto-any: https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fcnmapos%2Fmapboxgl-syncto-any
点击关注公众号,“技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线