样式

CSS Modules

在样式开发过程中,有两个问题比较突出:

  • 全局污染 —— CSS 文件中的选择器是全局生效的,不同文件中的同名选择器,根据 build 后生成文件中的先后顺序,后面的样式会将前面的覆盖;

  • 选择器复杂 —— 为了避免上面的问题,我们在编写样式的时候不得不小心翼翼,类名里会带上限制范围的标示,变得越来越长,多人开发时还很容易导致命名风格混乱,一个元素上使用的选择器个数也可能越来越多,最终导致难以维护。

好在 vue 为我们提供了 scoped 可以很方便的解决上述问题。它顾名思义给 css 加了一个域的概念。

  1. /* 编译前 */
  2. .example {
  3. color: red;
  4. }
  5. /* 编译后 */
  6. .example[_v-f3f3eg9] {
  7. color: red;
  8. }

只要加上 <style scoped> 这样 css 就只会作用在当前组件内了。详细文档见 vue-loader

TIP

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

目录结构

vue-element-admin 所有全局样式都在 @/src/styles 目录下设置

  1. ├── styles
  2. ├── btn.scss # 按钮样式
  3. ├── element-ui.scss # 全局自定义 element-ui 样式
  4. ├── index.scss # 全局通用样式
  5. ├── mixin.scss # 全局mixin
  6. ├── sidebar.scss # sidebar css
  7. ├── transition.scss # vue transition 动画
  8. └── variables.scss # 全局变量

常见的工作流程是,全局样式都写在 src/styles 目录下,每个页面自己对应的样式都写在自己的 .vue 文件之中

  1. <style>
  2. /* global styles */
  3. </style>
  4. <style scoped>
  5. /* local styles */
  6. </style>

自定义 element-ui 样式

现在我们来说说怎么覆盖 element-ui 样式。由于 element-ui 的样式我们是在全局引入的,所以你想在某个页面里面覆盖它的样式就不能加 scoped,但你又想只覆盖这个页面的 element 样式,你就可在它的父级加一个 class,用命名空间来解决问题。

  1. .article-page {
  2. /* 你的命名空间 */
  3. .el-tag {
  4. /* element-ui 元素*/
  5. margin-right: 0px;
  6. }
  7. }

当然也可以使用深度作用选择器 下文会介绍

父组件改变子组件样式 深度选择器

当你子组件使用了 scoped 但在父组件又想修改子组件的样式可以 通过 >>> 来实现:

  1. <style scoped>
  2. .a >>> .b { /* ... */ }
  3. </style>

将会编译成

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

如果你使用了一些预处理的东西,如 sass 你可以通过 /deep/ 来代替 >>> 实现想要的效果。

所以你想覆盖某个特定页面 element 的 button 的样式,你可以这样做:

  1. .xxx-container >>> .el-button{
  2. xxxx
  3. }

官方文档

Autoprefixer [新版本已无该问题]

vue-cli 有一个小坑,它默认 autoprefixer 只会对通过 vue-loader 引入的样式才会有有作用,换而言之也就是 .vue 文件里面的 css autoprefixer 才会效果。相关问题 issues/544 , issues/600 。解决方案也很简单粗暴

  1. //app.vue
  2. <style lang="scss">
  3. @import './styles/index.scss'; // 全局自定义的css样式
  4. </style>

你在 .vue 文件中引入你要的样式就可以了,或者你可以改变 vue-cli 的文件在 css-loader 前面在加一个 postcss-loader,在前面的 issue 地址中已经给出了解决方案。不过新版本已经默认解决处理了这个问题。

Postcss

这里再来说一下 postcss 的配置问题,新版的 vue-cli webpack 模板 init 之后根目录下默认有一个.postcssrc.js 。vue-loader 的 postcss 会默认读取这个文件的里的配置项,所以在这里直接改配置文件就可以了。配置和 postcss是一样的。

  1. //.postcssrc.js
  2. module.exports = {
  3. "plugins": {
  4. // to edit target browsers: use "browserslist" field in package.json
  5. "autoprefixer": {}
  6. }
  7. }
  8. //package.json
  9. "browserslist": [
  10. "> 1%",
  11. "last 2 versions",
  12. "not ie <= 8"
  13. ]

如上面代码所述的,autoprefixer 会去读取 package.json 下 browserslist 的配置参数

  • > 1% 兼容全球使用率大于 1%的浏览器
  • last 2 versions 兼容每个浏览器的最近两个版本
  • not ie <= 8 不兼容 ie8 及以下
    具体可见 browserslist

postcss也还有很多很多其它的功能大家可以自行去探究

Mixin

本项目没有设置自动注入 sass 的 mixin 到全局,所以需要在使用的地方手动引入 mixin

  1. <style rel="stylesheet/scss" lang="scss">
  2. @import "src/styles/mixin.scss";
  3. </style>

如需要自动将 mixin 注入到全局 ,可以使用sass-resources-loader

原文: https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/style.html