• vue中修改子组件(或第三方组件库)样式


    一、问题叙述

      项目里需要新添加一个表单页面,里面就只是几个select,这个几个select是原本封装好的组件,有自己原本的样式,而这次的原型图却没有和之前的样式统一起来,需要微调一下,这里就涉及到父组件修改子组件的样式。不想混用本地和全局样式,所以选择了>>>,但是并不起作用,就换成/deep/,其实到这里我也没有继续深入这个知识点,因为在浏览器里预览后已经实现了原型图的样式,直到打包在手机上测试,发现问题,在手机上浏览并没有将样式修改过来。如下图:

     

    问题:①为什么使用>>>不起作用?②为什么我使用了/deep/却没有成功的在手机上将样式修改过来?

    二、相关知识点

      ㈠关于vue中使用scoped属性

    在vue组件中,在style标签中添加scoped属性,这样在这里定义的css只作用于当前组件中的元素,可使组件之间的样式不会相互污染,使样式私有化。比如在父组件内使用子组件,父组件的样式不会渗透到子组件中。

      Ⅰ、在加上scoped后,会为DOM节点自动添加一个唯一的属性(data-v-f3f3eg9后面这串数字像是独一无二的hash值),以保证其唯一性。同时在相应的css选择器末尾,也加上了当前组件的data-v-f3f3eg9属性,来使其私有化。

    如Vue Loader中所给出的代码示例:

    <template>
      <div class="example">hi</div>
    </template>
    
    <style scoped>
    .example {
      color: red;
    }
    </style>

    转化后:

    <template>
      <div class="example" data-v-f3f3eg9>hi</div>
    </template>
    
    <style>
    .example[data-v-f3f3eg9] {
      color: red;
    }
    </style>

      ㈡关于深度作用选择器:/deep/(>>>)

      使用了scoped后,尽管实现组件样式的私有化,但在我们实际的项目中,在很多地方使用重复的子组件或其他的样式库时,在个别地方需要微调样式,这个时候不能直接改子组件样式,而且在父组件里的样式又不能渗透到子组件去。这个时候文档中有一句话:

    不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。

      所以还是有办法解决刚才那个问题的,当我们希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符,编译后会在相应的选择器后面增加独有的属性;如下:

    <style scoped>
    .a >>> .b { /* ... */ }
    </style>

    上述代码将会编译成:

    .a[data-v-f3f3eg9] .b { /* ... */ }

      在这里需要注意的是,有些像 Sass 、scss之类的预处理器无法正确解析 >>>。这种情况下我们可以使用 /deep/ 或 ::v-deep 操作符来取代>>>,这是两个都是 >>> 的别名,同样可以正常工作。如下:

    <style lang='scss' scoped>
    .a {
        /deep/ .b{
                    /* ... */
        }
    }
    </style>

    三、问题解决

      ①为什么使用>>>不起作用?

      因为这个项目使用的scss,所以无法正常解析>>>,所以在父组件没有渗透下去。

    .pop-content {
       .input-wrapper >>>  .form-item {
        .form-label {
         /*...*/
      }

      在浏览器查看转换的结果发现,还是原本组件的样式,我新定义的并没有出现。如下图:

      ②为什么我使用了/deep/却没有成功的在手机上将样式修改过来?

      因为引用的这个子组件里还包裹了一层子组件,我使用了两个/deep/,不理解/deep/的实现原理,自以为每一个组件都要渗透一次。

    /*错误代码:写了两次/deep */
    .pop-content {
      /deep/ .input-wrapper /deep/  .form-item {
          ...
      } 
     }

    转换后在浏览器看到的代码,发现第二个是无法转换的。

    .pop-content[data-v-b93cf8e0] .input-wrapper /deep/ .form-item {}
    /*修改后的代码*/
    .pop-content {  
         .input-wrapper /deep/  .form-item {  
        }
      }​
    
    /*编译转换后的代码*/
     .pop-content .input-wrapper[data-v-b93cf8e0] .form-item 

      ③随之而来第三个问题,我只写一个/deep/的话,我写在哪个位置呢,是不是写在哪都行,它们之间有什么区别。

      ⅰ尝试一:将/deep/写在input-wrapper后面

    .pop-content { 
       .input-wrapper /deep/  .form-item {
        padding: 0.4rem 2rem 0.3rem 1.5rem;
        .form-label {
          -webkit-box-flex: 0;
          -ms-flex: 0 0 8rem;
          flex: 0 0 50%;
          font-size: 15px;
          color: black;
          position: relative;
        }
      }

    转换后的样式代码:原本的样式已经失效了,并在input-wrapper后面添加了相应唯一的data-v属性值。

      ⅱ尝试二:将/deep/写在pop-content后面

    .pop-content {
      /deep/  .input-wrapper .form-item {
        padding: 0.4rem 2rem 0.3rem 1.5rem;
        .form-label {
          -webkit-box-flex: 0;
          -ms-flex: 0 0 8rem;
          flex: 0 0 50%;
          font-size: 15px;
          color: black;
          position: relative;
        }
      }

    转换后的样式代码:原本的样式已经失效了,并在pop-content后面添加了相应唯一的data-v属性值。

      ⅲ尝试三:将/deep/写在form-item或者form-label后面,均不起作用。看了一下DOM结构,我觉得可能是因为这样做的css的优先级并没有比原来的高,所以没法改变。还有就是这个子组件内部的组件嵌套也比较复杂,所以从最外面的父组件看不出,所以对/deep/位置的放置对其优先级的影响还是比较大的。大致这样理解。

  • 相关阅读:
    页面头部出现空白,页面头部出现 隐藏字符
    使用TortoiseGit对Git版本进行分支操作
    文件夹添加右键DOS快捷入口
    android离线安装adt
    V9最新手机门户域名绑定教程。
    phpcms v9 模板标签说明整理
    CAM350 10.5移动和叠层的用法
    MOS简单应用
    c语言知识点总结-------静态区、堆、栈、常量区等
    C语言关键字—-sizeof 、typedef、const、static、register、extern、#define
  • 原文地址:https://www.cnblogs.com/songForU/p/11176696.html
Copyright © 2020-2023  润新知