zoukankan      html  css  js  c++  java
  • vue中的css作用域、vue中的scoped坑点

    一、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{
             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>标签,所以上面的写法是没有问题的。

    转自:https://www.cnblogs.com/goloving/p/9119460.html

  • 相关阅读:
    Oracle 11g SQL Fundamentals Training Introduction02
    Chapter 05Reporting Aggregated data Using the Group Functions 01
    Chapter 01Restriicting Data Using The SQL SELECT Statemnt01
    Oracle 11g SQL Fundamentals Training Introduction01
    Chapter 04Using Conversion Functions and Conditional ExpressionsConditional Expressions
    Unix时代的开创者Ken Thompson (zz.is2120.bg57iv3)
    我心目中计算机软件科学最小必读书目 (zz.is2120)
    北京将评估分时分区单双号限行 推进错时上下班 (zz)
    佳能G系列领军相机G1X
    选购单反相机的新建议——心民谈宾得K5(转)
  • 原文地址:https://www.cnblogs.com/javalinux/p/15602201.html
Copyright © 2011-2022 走看看