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

17 篇文章 0 订阅

vue中的css作用域、vue中的scoped坑点icon-default.png?t=LBL2https://www.cnblogs.com/goloving/p/9119460.html

一、css作用域

  之前一直很困扰css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的。导致在css中需要加上对应模块的html的id/class 使用css选择器 保证css的作用域不会变成全局 而被其它模块的css污染。

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

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

.parent >>> .children{ /* ... */ }

.parent /deep/ .children{ /* ... */ }

二、scoped坑点

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

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

复制代码

//valChange.less(使用了嵌套规则)
#valueSlide{
    .bigSlider .ivu-slider-wrap{
        height: 6px;
    }
    .bigSlider .ivu-slider-bar {
        height: 6px;
    }
    .bigSlider .ivu-slider-button{
        width: 14px;
        height: 14px;
    } 
}

//html部分
<style lang="less" scoped>
    @import "./valChange.less";
</style>
<div class="valid-panel">
    <div class="containerBox">
        <div id="valueSlide" v-bind:style="validStyle">
            <Slider ></Slider>
        </div>
    </div>
</div>

复制代码

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

  HTML部分:

  CSS部分:

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

  • 给HTML的DOM节点加一个不重复data属性(形如:data-v-19fca230)来表示他的唯一性
  • 在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式

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

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

  解决方案:

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

  总结一下scoped三条渲染规则:

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

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

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

  问题补充:

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

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

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

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

<style lang="less">
    @import "./test.less";
</style>

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

复制代码

<style lang="less" scoped>
    @import "./test.less";
</style>
<style lang="less">
    //你的覆盖样式
</style>

复制代码

  这样既覆盖了样式,其他样式不会被覆盖到全局,感兴趣的同学可以自己试一试。(注意两个标签的顺序)。

  官网 vue-loader 中提到每个vue模板中可以有多个<style></style>标签,所以上面的写法是没有问题的。

分类: Vue3/Vue2框架生态链

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue,可以使用`scoped`属性来实现CSS作用域。当`<style>`标签有`scoped`属性时,它的CSS只会作用于当前组件的元素,类似于Shadow DOM的样式封装。这可以通过使用PostCSS来实现转换。例如: ```vue <style scoped> .example { color: red; } </style> <template> <div class="example">hi</div> </template> ``` 在上述例子,`.example`类的样式只会应用于该组件内的`<div>`元素。 如果希望在scoped能够深度影响样式,可以使用`>>>`或者`/deep/`选择器。例如: ```vue <style lang="scss" scoped> .search { /deep/ .el-input { width: sizeTranslate(180rem); } } </style> ``` 使用`/deep/`选择器可以让`.el-input`样式深度影响`.search`类的元素。 需要注意的是,在开发环境改变单个Vue组件的样式可能不会影响其他组件,但在服务器上会生效。这是由于Vue的编译过程和构建配置的不同导致的差异。 总结:VueCSS作用域是通过`scoped`属性实现的,可以将样式限定在当前组件的元素。如果需要深度影响样式,可以使用`>>>`或者`/deep/`选择器。需要注意在开发环境和服务器上的样式变化可能会有差异。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vuecss作用域](https://blog.csdn.net/wang0112233/article/details/103576632)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Vue作用域CSSCSS模块的区别](https://download.csdn.net/download/weixin_38705004/12951030)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值