vue 中 style scope 深度访问方式汇总 (::v-deep)
我们的 vue 组件中 style 有 scope 属性
<style scoped> </style>
作用功能:
实现组件样式的私有化,样式不对全局造成样式污染,表示当前 style 属性只属于当前模块组件
实现原理:
添加 scoped属性 的组件,为了达到不污染全局,做了如下处理:
给 HTML 的 DOM 节点加一个不重复属性 data-v-xxxxxxx 唯一性标志
在添加scoped属性的组件的每个样式选择器后添加一个等同与“不重复属性”相同的字段,实现类似于“作用域”的作用,不影响全局
如果组件内部还有组件,只会给最外层的组件里的标签加上唯一属性字段,不影响组件内部引用的组件( 注意 )
scope 慎用:
从原理可见,之所以 scoped 可达到类似组件私有化、样式设置“作用域”的效果,其实只是在设置 scoped 属性的组件上的所有标签添加一的 data 开头的属性,且在标签选择器的结尾加上和属性同样的字段,起到唯一性的作用,但是这样如果组件中也引用其他组件就会出现类似下面的问题:
父组件无 scoped 属性,子组件带有 scoped,父组件可通过子组件样式选择器修改子组件样式
父组件有 scoped 属性,子组件 无,父组件无法设置子组件样式,因为父组件的所有标签都会带有 data-v-469af010 唯一标志,但子组件不会带有这个唯一标志属
父/子组件都有,同理也无法设置样式,更改起来增加代码量
解决方法
父/子组件都有 scope,可以在父组件中改子组件样式,可以通过在父组件中添加样式穿透来修改子组件样式,
css 样式穿透 >>>
less scss 加 /deep/ 前缀,不会影响其他地方子组件使用
vue 新方式 ::v-deep
除了样式穿透,还可以通过在父组件中再添加一个没有 scope 的 style,来通过样式选择器去设置子组件样式,且不影响全局样式;
父组件添加了 scoped ,子组件无论加不加 scoped,父组件不能通过子组件的样式选择器来修改子组件样式;
父组件不添加 scoped,子组件添加 scoped,父组件是可以通过子组件样式选择器来修改子组件的样式;
vue 中 style scope 深度访问方式
如果 vue 的 style 使用的是 css,那么使用 >>>:
<style scoped> .a >>> .b { /* ... */ } </style>
但是像 scss 等预处理器却无法解析 >>>,我们使用 /deep/
<style scoped> .a{ /deep/ .b { /* ... */ } } </style>
在 vue-cli3 编译时,deep 的方式会报错或者警告,我们可使用新方式: ::v-deep;切记必须是双冒号
<style scoped> .a{ ::v-deep .b { /* ... */ } } </style>
使用场景
当我们在组件中需要覆盖 element-ui 中的样式时只能通过深度作用选择器
1. style 为 css 时的写法如下
#div1 .a >>> .b { *** }
2. style 使用 css 的预处理器 (less, sass, scss) 的写法如下
第一种/deep/
#div1 /deep/ .a { *** }
第二种::v-deep
#div1 ::v-deep .a{ *** }
推荐使用第二种方式 ::v-deep,因为 /deep/ 在某些时候会报错, ::v-deep 更保险并且编译速度更快.
共 0 条评论