Bootstrap

vue项目中,scss 使用 /deep/ 穿透写法

当 <style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。这类似于 Shadow DOM 中的样式封装。它通过使用 PostCSS 来实现以下转换:

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

PostCSS 给一个组件中的所有 DOM 添加了一个独一无二的动态属性,然后给 CSS 选择器额外添加一个对应的属性选择器来选择该组件中 DOM,这种做法使得样式只作用于含有该属性的 DOM——组件内部 DOM。

问题描述:当我们需要修改 element-ui 内部组件的样式时,我们通常将内部组件的样式放在一个 class 作用域下,同时使用全局作用域的样式去修改默认 ui 样式,代码如下:

<style lang="scss">
  .button-box{
    .el-button{
      padding: 13px 50px;
    }
  }
</style>

混用本地和全局样式

你可以在一个组件中同时使用有 scoped 和非 scoped 样式:

<style>
/* 全局样式 */
</style>

<style scoped>
/* 本地样式 */
</style>

如果我们依然使用当前组件的 scoped 属性,那我们如何去修改 element-ui 内部的样式呢?引用了第三方组件,需要在组件中局部修改第三方组件的样式,而又不想去除 scoped 属性造成组件之间的样式污染。此时只能通过特殊的方式,穿透 scoped。下面我们就会介绍这个深度作用选择器。

深度作用选择器

如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符:

<style scoped>
.a >>> .b { /* ... */ }
</style>
// 上述代码将会编译成:
.a[data-v-f3f3eg9] .b { /* ... */ }

有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。

<style lang="scss" scoped>
  .button-box{
    /deep/ .el-button{
      padding: 13px 50px;
    }
  }
</style>

更多详情,请查看 Vue-loader 官网之 Scoped CSS

补充:webpack 之解析 CSS 文件。

webpack 将一切文件视为模块,而 webpack 只能解析 JS 文件,如果想将其他问题也打包的话,这是我们就会用到 Loader。Loader 被称为加载器,其作用是让 webpack 可以加载和解析非 JS 文件的能力。下面我们介绍跟 css 有关的几个加载器:

style-loader: 把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS;

css-loader:加载 CSS,支持模块化、压缩、文件导入等特性;

postcss-loader:做浏览器兼容性的;

sass-loader:将 scss 文件信息解析成 css 信息。

module.exports = {
    entry: path.join(srcPath, 'index'),
    module: {
        rules: [{
            test: /\.css$/,
            // loader 的执行顺序是从后往前
            loader: ['style-loader', 'css-loader', 'postcss-loader'],
        },{
            test: /\.scss$/,
            // loader 的执行顺序是从后往前
            loader: ['style-loader', 'css-loader', 'scss-loader'],
        }]
    },
    plugins: [
        ......
    ]
}
 
;