zoukankan      html  css  js  c++  java
  • 大白话理解scoped

    在style标签设置scoped属性,可以使组件之间的样式不互相污染,达到样式私有模块化的目的。

    接下来,我们分别从原理、优缺点、解法来认识下

    原理:

    style标签设置scoped属性,经过PostCSS转译后,在DOM结构以及css样式上加唯一的标记:data-v-hash属性,意味着CSS样式就只能作用于当前组件,从而使得组件之间的样式不互相污染,达到样式私有模块化的目的。 

    1)当前组件的DOM根节点及其子节加一个不重复data属性(如data-v-19fca230),

    2)当前组件引入子组件,那么,给子组件的根节点加上当前组件的data属性

    3)在每句css选择器的末尾加一个当前组件的data属性选择器(如data-v-19fca230)

    举个例子

    例一:

    <template>
      <div class="wrap">
        <h1 class="parent1"> hello </h1>
        <h1 class="parent2"> hi </h1>
    </div>
    </template>
    <style scoped>
        .wrap{
            backgorund: lightsalmon
         .parent1{
           color: red
         } }
    .parent2{
       color: green
     }
    </style> 

    转译后, 当前组件的Dom根节点及子节点都有了一个[data-v-5406a40e]属性,其选择器末尾加一个当前组件的[data-v-5406a40e]属性

       

    例二:引入子组件

    // 父组件
    <template> <div class="wrap"> <h1 class="parent">当前组件1</h1> <childCompontent class="childCompontent"></childCompontent>   </div> </template> <style scoped> .childCompontent{ backgorund: lightgreen } </style>
    // 子组件
    <template>
        <div>
        <h1 class="child-wrap">子组件</h1>
      </div>
    </template>
    <style scoped>
      .child-wrap{
        color: lightpink
      }
    </style>  

    转译后,

    当前组件引入子组件,在子组件的style标签加了scoped,  那么,仅子组件的Dom根节点会带有父组件相同的[data-v-5406a40e]属性。

    带有childCompontent的标签,其选择器末尾加一个当前父组件的[data-v-5406a40e]属性,而引入的child-wrap的标签,其选择器末尾加一个当前组件,也就是子组件组件的[data-v-180cce0f]属性

      

    要是想在当前父组件中修改子组件的样式,怎么办呢? 

    直接修改,如下

    // 父组件
    <template> <div class="wrap"> <childCompontent class="childCompontent"></childCompontent>   </div> </template> <style scoped>
    .wrap .child-wrap{
    color: red
    }
    </style>

    结果,没有生效。那是因为渲染后,css选择器样式如下:

    // 父组件渲染后
    .wrap .child-wrap[data-v-5406a40e] { color: red; }
    // 子组件渲染后
    .child-wrap[data-v-180cce0f] { 
      color: lightpink;
    }

    目标子组件css选择器是.child-wrap[data-v-180cce0f] ,而我们在父组件修改的是data-v-5406a40属性的child-wrap,根本作用不到我们想要的DOM节点上,

    这种情况我们在父组件内部写的任何样式都不会影响到子组件组件,所以这就尴尬了。。。。

    解决方法:

    1)在模板中使用两次style标签:一个用于私有样式(带scoped属性),一个用于共有样式

    <style lang="scss">
        /* 需要覆盖的样式--注意css权重 */
     
    .wrap .childCompontent .child-wrap{
        color: red
      }
    </style>
    <style lang="scss" scoped>
        /* 当前组件的私有样式 */
    </style>

    2)使用 >>> 或者 /deep/ 操作符  (Sass、Less等预处理器无法正确解析 >>>,可以使用/deep/ )

    <style lang="scss" scoped>
    .wrap /deep/ .child-wrap {
        color: red 
      }
    }
    </style>

    参考Vue loader官方文档 

  • 相关阅读:
    清北学堂(2019 5 3) part 6
    清北学堂(2019 5 2) part 5
    清北学堂(2019 5 1) part 4
    dijkstra
    清北学堂(2019 4 30 ) part 3
    2020/5/1
    2020/4/30
    2020/4/29
    HSV模型
    2020/4/28
  • 原文地址:https://www.cnblogs.com/renzm0318/p/11877361.html
Copyright © 2011-2022 走看看