Vue+ElementUI项目sass样式管理

830 阅读4分钟

在项目中使用sass预处理样式,可以方便我们从整体去把控项目的风格,这很大一部分是因为sass可以使用变量和混合器。

前段时间在重构一个vue管理后台项目,结合了之前项目的实践、开源项目和ElementUI的样式管理方式,最终整理了一份自己的样式库。其中最有启示的是ElementUI的样式管理方式,我们一起来看看它是怎么管理样式的,先上图:

image.png

  1. 红色框部分是一些公共的样式,popup.scss是modal类组件的样式,transition.scss是各种转变的效果样式,对我们而言,var.scss的研究价值最高。var.scss文件控制了ElementUI的整体样式风格,有主题颜色、border、字体、圆角等的设置,ElementUI官网提供了主题定制的功能,其本质就是通过可视化配置,让我们自己去定制这些变量,然后根据这些变量重新下载一套css样式,引入项目中,重写框架默认的样式,从而达到定制主题的目的。如果你觉得从官网下载主题css样式不够灵活,你可以在自己的样式库重写变量,因为var.scss文件的变量都是默认值(即变量后面都跟了!default),我们只需要声明一个对应的变量名并赋值,然后引入element的sass样式库’element-ui/packages/theme-chalk/src/index‘,就可以灵活地自定义主题。
  2. 绿色框部分是一些可以公用的样式块,像button不同状态但是处理逻辑一样的,一些可以兼容多浏览器的写法等都可以抽取出来,方便维护和迭代。
  3. 蓝色框是个组件的样式,每个组件一个scss文件,方便管理,在每个组件样式中,通过引入common和mixins里面的样式的方式,保证了风格统一性。因为组件样式太多,没截取全,蓝色框部分有一份index.scss文件,index.scss文件主要是引入各个组件和公共样式文件,这也就解释了,为什么在1处强调需要引入’element-ui/packages/theme-chalk/src/index‘样式库文件。

有了上面的启示,我整理了一下样式库,先上图:

image.png

  1. login主要用来放登录页的样式。
  2. index用来import所有public文件夹下的样式文件。
  3. common是一些重置html标签的样式,避免因为不同浏览器标签内置样式不同导致的样式问题。
  4. icon用来放项目中一些icon样式,比如一些系列icon,放同一张大png图上,通过控制背景位置不同,显示不同icon,这类样式可以放在这。
  5. mixins,sass混合器文件,比如清除浮动、省略号、滚动条、阴影、浏览器兼容性等样式块可以放在这里。
  6. override,主要用于重写ElementUI样式,无法通过主题变量满足的需求,像表格的行高、边距、鼠标悬停行背景色等,dialog/pagination/button等组件变量不可控的样式,我们可以在这里重写而达到目的。
  7. size,主要是一个for循环用于生成一份基础padding、margin边距样式,几乎每个经手的系统我都会引入,十分好用,文件内容粘到文章末尾。
  8. theme,用来重写var.scss文件变量的文件,根据需要自定义组件的主题。
  9. transition,用来放各种动画交互效果公用样式。
  10. variables,主要用来存放主题颜色、不同等级标题的字体颜色、不同正文字体颜色、borderRadius、borderColor等项目中统一使用的变量,这部分变量可以结合项目高保真图和UI部门的设计规范来定。一般这份文件会频繁引入各页面中,以达到项目整体风格统一性,也方便后续维护。

最后,贴上size.scss文件内容,生成一系列class,间距为4倍数,如mr-1表示margin-right:4px;p-2表示padding:8px;等,以此类推。

@each $p,$v in (p:padding,m:margin) {
  @for $i from 0 to 20 {
    .#{$p}-#{$i}{#{$v}:$i*4px};
    .#{$p}l-#{$i}{#{$v}-left:$i*4px};
    .#{$p}r-#{$i}{#{$v}-right:$i*4px};
    .#{$p}t-#{$i}{#{$v}-top:$i*4px};
    .#{$p}b-#{$i}{#{$v}-bottom:$i*4px};
    .#{$p}x-#{$i}{#{$v}-left:$i*4px;#{$v}-right:$i*4px};
    .#{$p}y-#{$i}{#{$v}-top:$i*4px;#{$v}-bottom:$i*4px};
  }
  .#{$p}-auto{#{$v}:auto};
  .#{$p}l-auto{#{$v}-left:auto};
  .#{$p}r-auto{#{$v}-right:auto};
  .#{$p}t-auto{#{$v}-top:auto};
  .#{$p}b-auto{#{$v}-bottom:auto};
  .#{$p}x-auto{#{$v}-left:auto;#{$v}-right:auto};
  .#{$p}y-auto{#{$v}-top:auto;#{$v}-bottom:auto};
}