zoukankan      html  css  js  c++  java
  • 深度解析为什么vue组件中添加scoped后某些样式不生效?给出解决办法

    转载自:

    版权声明:本文为CSDN博主「Ardor-Zhang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_41800366/article/details/107062781

    参考:https://vue-loader.vuejs.org/zh/guide/scoped-css.html#%E6%B7%B7%E7%94%A8%E6%9C%AC%E5%9C%B0%E5%92%8C%E5%85%A8%E5%B1%80%E6%A0%B7%E5%BC%8F

    1 简述
    博主近期使用 vue 时写发现某些样式不生效,怎么都不生效, 不过将style 中的 scoped 去掉后,居然生效了,那么出现样式不生效的原因肯定就是 scoped 捣的鬼,在仔细研究过后得出了一些结论,包括为什么会出现这种情况和解决办法,在此分享。

    2 深度解析
    为了便于展示和理解,博主在这里选择了一父组件和一子组件,
    父组件: 首先,父组件引入子组件TestScoped

    <template>
      <div class="parent">
      <p>Here is parent component</p>
      <TestScoped />
      </div>
    </template>
    <style>
    .parent {
        color: deepskyblue;
    }
    </style>


    子组件: TestScoped

    <template>
      <div class="son">
      <p>Here is son component</p>
      </div>
    </template>
    

    2.1 不添加 scoped
    此时的HTML编译后的结果是:

    <div class="parent">
      <p>Here is parent component</p>
      <div class="son">
        <p>Here is son component</p>
      </div>
    </div>
    

    没错,是我们所理解的样子,这时候因为在父组件中添加了如是的样式,那么肯定子组件的Here is son component也带有这个样式,结果的确是这样。

    <style>
    p {
      color: deepskyblue;
    }
    </style>


    渲染后的结果。


    2.2 添加 scoped
    也就是在父组件的style中添加scoped

    <style scoped>
    .p {
      color: deepskyblue;
    }
    </style>
    

     

    此时的HTML编译后的结果是:

    <div data-v-7ba5bd90 class="parent">
      <p data-v-7ba5bd90>Here is parent component</p>
      <div data-v-7ba5bd90 class="son">
        <p>Here is son component</p>
      </div>
    </div>
    

    此时的编译结果也能够理解,也就是 vue 给父组件的每一个标签自动添加一个唯一的 attribute, 这里 注意,你会发现vue给子组件的根标签也打上了这一个唯一的attribute, 但是子组件的其他标签却没有打上。

    编译后会发现,添加的css样式变成了如下:添加了唯一的标签,这也就是vue scoped 实现样式隔离的原理

    p[data-v-7ba5bd90] {
      color: deepskyblue;
    }


    由于子组件中除根标签以为其他都未打上父组件的唯一标签,那么可想而知,样式不会在子组件中生效,结果的确如此。

    总结: 为什么vue组件中添加scoped后某些样式不生效?
    原因: vue的scoped为本组件的所有标签都打上了一个唯一attribute,样式生效时也带上了这唯一的attribute,但是本组件应用的所有子组件,除根标签以为其他都未打上这唯一标签,因此样式自然不会生效。

    3 解决办法
    3.1 官方解决办法
    点击查看官方解决办法
    vue给出的解决办法是: 深度作用选择器
    如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符
    有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。

    通常我们会选择/deep/,使用方式如下,在需要子组件样式生效的地方加上/deep/

    <style scoped>
    /deep/p{
      color: deepskyblue;
    }
    </style>


    此时HTML编译结果不会改变,只是样式的生效方式不同了,变成了如下:

    [data-v-7ba5bd90] p {
      color: deepskyblue;
    }

    这样便使得css生效


    3.2 博主选择的解决办法
    博主一般不会使用/deep/,因为嫌麻烦,每一个要用的地方都得写,因此,博主的选择是采用两个style,其中一个添加scoped,写组内的样式,另一个不添加,修改子组件的样式

    <style scoped>
    p{
      color: deepskyblue;
    }
    </style>
    
    <style>
    
    </style>


    相信只要你看完这篇博文,你肯定能够完全理解为什么scoped后样式不起作用了

  • 相关阅读:
    JqGrid在IE8中表头不能分组的解决办法
    Task 异步小技巧
    封装好的socket,拿去用
    反射 实现不同模型相同属性赋值 第二集(automapper)
    .net破解二(修改dll)
    .net破解一(反编译,反混淆-剥壳)
    c/s 自动升级(WebService)
    反射实现不同模型相同属性赋值
    row_number() over()分页查询
    SQL函数
  • 原文地址:https://www.cnblogs.com/jeacy/p/15767578.html
Copyright © 2011-2022 走看看