vue中的css作用域、vue中的scoped坑点

lxf2024-04-06 12:10:50

  之前一直很困扰css的作用域问题,即使是模块化编程下,在对应的模块的js中import

  css进来,这个css仍然是全局的。导致在css中需要加上对应模块的html的id/class 使用css选择器

  保证css的作用域不会变成全局 而被其它模块的css污染。

  在vue中引入了scoped这个概念,scoped的设计思想就是让当前组件的样式不会修改到其它地方的样式,使用了data-v-hash的方式来使css有了它对应模块的标识,这样写css的时候不需要加太多额外的选择器,方便很多。

  但是要注意scoped的作用域,因为权重的问题,如果是在子组件使用了scoped,那么在父组件中是不能直接修改子组件的样式的,需要在父组件中使用vue的深度作用选择器。

  今天在覆盖iview组件样式的时候发现一个问题,就是无法覆盖组件原有的样式,最后在github的中找到了答案: 不要使用属性。于是我查找了下关于的文章。

  我们假设把这种组件叫做模块私有组件,其他的未加scoped的叫做模块一般组件。通过查看DOM结构发现:vue通过在DOM结构以及css样式上加唯一不重复的标记,以保证唯一,达到样式私有化模块化的目的。

  也就是我们在style中使用scoped属性会出现下面的情况:

  HTML部分:

  vue中的css作用域、vue中的scoped坑点

  CSS部分:

  vue中的css作用域、vue中的scoped坑点

  从上面的字可以看出,添加了scoped属性的组件,为了达到组件样式模块化,做了两个处理:

  那么问题来了: 对于当前组件下调用的其他组件,属性只会添加到第一层HTML中:

  vue中的css作用域、vue中的scoped坑点

  对于我们想覆盖的样式则无法起到作用:(在浏览器调试中手动添加 [data-v-19fca230] 属性后可以匹配)

  解决方案:

  不使用属性,更多详细介绍可以参考这篇文章

  总结一下三条渲染规则:

  1、给HTML的DOM节点加一个不重复data属性(形如:)来表示他的唯一性

  2、在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的属性选择器(如)来私有化样式

  3、如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性

  问题补充:

  1、如果不使用如何解决样式全局污染?

  推荐使用推动组件私有化,文章所提到的不使用仅出现在已有UI库的样式覆盖上(当然人家用了 那就很难办了)。

  首先,解决组件样式全局污染,也就是我们在这里不使用 覆盖了样式,那么我们在其他地方调用该组件就会被覆盖。那么我们在使用组件的时候对组件给一个类名 或者其他甄别属性(id),覆盖样式就针对该类名进行重写样式。

  其次,解决其他样式全局污染,如果我们通过:

  <style lang="less">

  @import "http://rank.chinaz.comwww.qdxiaochuan.com/test.less"; 

  </style>

   

  引进样式,那么不使用 , 中的其他类名样式可能会污染全局,我这里用一个比较笨的方法处理:在模板中使用两次 标签:

  <style lang="less" scoped>

  @import "http://rank.chinaz.comwww.qdxiaochuan.com/test.less"; 

  </style> 

  <style lang="less">

  //你的覆盖样式 

  </style>