• css modules的一些实践


    本人使用vue引入css modules做实践。vue文档查看:https://vue-loader-v14.vuejs.org/zh-cn/features/css-modules.html 以及 https://vue-loader.vuejs.org/zh/guide/css-modules.html#%E7%94%A8%E6%B3%95

    简单的配置css-loader

      {
            loader: 'css-loader',
            options: {
                modules: true,
                importLoaders: 1,
                localIdentName: '[name]_[local]_[hash:base64:5]',
                camelCase: true
            }
        }

    然后 <style> 上添加 module 属性,就自动生成一个$style的计算属性可以用了

    <template>
      <p :class="$style.red">
          <span :class="$style.redBg" >This should be red</span>
      </p>
    </template>
    
    <style module>
    .red {
      color: red;
    }
    .red-bg{
       color: #A52A2A
    }
    </style>

    基本使用没有问题,自己弄个小demo也可以。再实际使用中遇到了坑

    引用的第三方组件element-ui不支持css module如何处理?

    element-ui这个组件库目前是不支持css modules的。使用默认的css modules后,element中的css文件都改成了css module形式,但是使用时html代码却没有用。比如下面这个alert弹窗。

    导致找不到样式,完全错乱了。

    解决方案:

    让需要进行css modules的文件才进行css modules

    //专门针对node_modules中的样式处理
    {
      test: /.css$/,
      use: ['vue-style-loader', 'css-loader'],
      include:[path.resolve(__dirname, '../node_modules')]
    },
    {
      test: /.css$/,
      use: ['vue-style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: true,
            importLoaders: 1,
            localIdentName: '[name]_[local]_[hash:base64:5]',
            camelCase: true
         }
      }],
      exclude:[path.resolve(__dirname, '../node_modules')]
    }

    这种方式是比较简单,但是也够粗暴。所有满足条件的文件夹下面的文件都会进行css modules【不管有没有为style添加module都会css modules,只是添加了module会得到一个计算属性$style】。但是情况往往不是那么简单的,复杂场景见下面的坑。

    顺利引入了Elment-ui,现在想要再本地覆盖某个element-ui的样式?工程中某些样式不想使用css modules又该如何?

    比如

    //element-ui的tab切换焦点样式为
    .el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
        color:#409EFF;
        background-color: #FFF;
        border-right-color: #DCDFE6;
        border-left-color: #DCDFE6;
    }
    
    //你要想在更改这个颜色在本地改写为
    .el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
        color:#ff0;
    }

    不好意思,本地的样式全部会转换为css modules,而element上的样式class还是原来的样子。打包之后两个class已经不一样了,无法覆盖

    还有本地某个样式不想使用css modules。比如common.scss有公用的按钮样式,想直接拿来用,不想再在当前文件建立一个新的样式。比如

    // common.scss中公用按钮样式
    /* 白底橙字圆角按钮 */
    .white-orange-btn{
      font-size: 14px;
      background: $ui-white;
      color: $ui-main;
    }
    
    
    // common.scss在入口html已经引用,在test.vue中直接使用,和css modules混用
    <template>
        <div>
            <button :class="['white-orange-btn', $style.btn]">按钮</button>
        </div>
    </template>
    
    <style module>
    .btn{
        width: 200px;
        height: 40px;
    }
    </style>

    common.scss也不属于node_modules,也进行了css modules,这里直接使用字符串‘white-orange-btn’是找不到的。而‘$style.whiteOrangeBtn’在本地也没有定义。

    所以上面两种情况,要解决的问题是:在vue的单文件组件内部,要能指定某些样式进行从css modules,某些样式不进行css modules。

    解决方案:

    使用 oneOf 规则并在 resourceQuery 字符串中检查 module 字符串

    // webpack.config.js -> module.rules
    {
      test: /.css$/,
      oneOf: [
        // 这里匹配 `<style module>`
        {
          resourceQuery: /module/,
          use: [
            'vue-style-loader',
            {
              loader: 'css-loader',
              options: {
                modules: true,
                localIdentName: '[local]_[hash:base64:5]'
              }
            }
          ]
        },
        // 这里匹配普通的 `<style>` 或 `<style scoped>`或者其他外部css
        {
          use: [
            'vue-style-loader',
            'css-loader'
          ]
        }
      ]
    }

    这样只有为style设置了module的才会进行css modules,其他情况不会进行css modules。

    【注】:如果style中使用lang="scss",则需要对.scss也要进行类似的配置

  • 相关阅读:
    受脑认知和神经科学启发的人工智能
    1分钟爱上管理学
    刻意练习
    课题设计相关
    销售必备心灵鸡汤(转)
    从优秀到卓越
    小记
    何谓成熟?
    三体运动的程序模拟
    行星运动轨迹的程序实现
  • 原文地址:https://www.cnblogs.com/chuaWeb/p/12520385.html
Copyright © 2020-2023  润新知