1、scoped 的实现原理
Vue中的Less 中的 scoped 属性的效果主要是通过 PostCss 实现的。代码示例:
//编译前 <template> <div class="example">scoped测试案例</div> </template> <style scoped lang="less"> .example{ color:red; } </style> //编译后 <template> <div class="example" data-v-5558831a>scoped测试案例</div> </template> .example[data-v-5558831a] { color: red; }
PostCSS 给一个组件中的所有 dom 添加了一个独一无二的动态属性(比如上面的data-v-5558831a),给 css 选择器额外添加一个对应的属性选择器来选择组件中的 dom ,这种做法使得样式只作用于含有该属性的dom元素(组件内部的dom)。
可以总结,scoped 的渲染规则:
- 给HTML的dom节点添加一个不重复的data属性(例如: data-v-5558831a)来唯一标识这个dom 元素
- 在每句css选择器的末尾(编译后生成的css语句)加一个当前组件的data属性选择器(例如:[data-v-5558831a])来私有化样式
2、scoped穿透
scoped在Vue项目中,当我们引入第三方组件库时,需要在局部组件中修改第三方组件库的样式,而又不想去除scoped属性造成组件之间的样式覆盖。这时我们可以通过特殊的方式穿透scoped。
stylus的样式穿透 使用>>>来进行穿透
外层 >>> 第三方组件
样式
.wrapper >>> .swiper-pagination-bullet-active
background: #fff
sass 和 less 的样式穿透使用 /deep/
外层 /deep/ 第三方组件 { 样式 } .wrapper /deep/ .swiper-pagination-bullet-active{ background: #fff; }
可以参考:https://segmentfault.com/a/1190000015932467
3、scoped使用中的问题
在 style 标签里添加 scoped 属性代表着 style 标签里的样式只会作用于该组件而不会作用于其他组件中,但其他公共样式仍会对该组件起作用。比如父子组件中,在父组件中添加了 scoped 属性,此时父组件中的样式并不会作用于子组件。
有个现象比较奇怪,在父组件中没有 scoped 属性,子组件中有,此时如果从父组件中打开子组件,父组件中设置的样式会对子组件起作用,但是如果直接跳转打开子组件页面的话,此时父组件中的样式就不会对子组件起作用了。所以我们在组件中设置样式应该尽量都添加 scoped 属性。