通过上一篇文章
ElementUI源码系列一 - 从零搭建项目架构,项目准备、项目打包、项目测试流程
的学习,我们搭好了项目的基本框架,如下,它们每个文件夹是各司其职,分工明确的。
这一章我们来学习一下,
ElementUI
中样式是如何被使用的,我们先来分析一波:
观察
element-ui
源码的
package.json
文件,可以知道它样式使用的是
scss
预处理语言;
在它的源码
packages/theme-chalk/src
路径下,我们还可以发现每个组件都有对应的
.scss
文件;
.scss
文件最终肯定是要变成
.css
文件才能被浏览器识别的,那么它又是如何转换的呢?从
package.json
文件可以知道它使用了
gulp
来做转换,在
packages/theme-chalk/src
目录下也有关于它的配置文件。(关于
gulp
可以先自行学习一下,后面会用它写一些功能)
(为了方便学习,你可以下载一份
element-ui
源码在本地进行对比学习,效果会更佳)
使用scss预处理器编写组件样式
经过上面的分析,我们先来尝试使用
.scss
来给组件添加一些样式,再逐步也将它进行转换。首先,我们先来把我们组件代码改一改,给
button
组件添加一个类名。
<template>
<button class="el-button">我是一个普通按钮</button>
</template>
<script>
export default {
name: 'ElButton'
</script>
其次,我们也和 ElementUI
一样,在相同目录下,给 button
组件创建相同的样式文件。
并给它写一个最简单的样式,随便先给一个背景色,能看出效果即可,后面会使用一些 scss
语法来编写样式:
.el-button {
background-color: red;
最后,我们引入处理 .scss
需要用到的包,一共会用到四个包:npm install gulp@4.0.0 gulp-autoprefixer@6.0.0 gulp-cssmin@0.2.0 gulp-sass@4.0.2 -D
稍微介绍下四个包的作用:
gulp:一种自动化构建工具,和我们熟知的 webpack
很相似,但它更纯粹一些,它基于 Node
流的能力去构建任务流,某些方面上更具性能优势,我们会采取它来处理 .scss
文件。
gulp-autoprefixer:由它的名字大概也能猜出它的作用了,用于自动补全 CSS
前缀的插件。
gulp-cssmin:用于压缩 CSS
。
gulp-sass:编译 scss
,转成 CSS
。
sass
和 scss
其实就是同一种东西,我们平时都称之为 sass
,它们俩的主要区别在于语法上,sass
是缩进语法为主,完全省略花括号;scss
是一种 CSS-like
语法,就比较接近 CSS
,更加友好和可读。
使用gulp把scss转成css、补全、压缩
写完 button.scss
样式文件后,要让它生效的第一步工作,我们就要把它转成 .css
文件才行。下面就正式开始 scss
的转换工作,我们先在 packages/theme-chalk
路径下创建一个 gulpfile.js
文件。
再编写 gulp
代码,代码不多,都是 gulp
插件使用的基本语法,应该不难哈。
const { series, src, dest } = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');
function compile() {
return src('./src/*.scss')
.pipe(sass.sync())
.pipe(autoprefixer({
browsers: ['ie > 9', 'last 2 versions'],
cascade: false
}))
.pipe(cssmin())
.pipe(dest('./lib'));
exports.build = series(compile);
写完配置文件,老样子,我们为这个转换操作配置一条命令,方便后期操作。
"scripts": {
"dev": "webpack-dev-server --config build/webpack.common.js",
"build": "webpack --config build/webpack.common.js",
"build:theme": "gulp build --gulpfile packages/theme-chalk/gulpfile.js"
现在在我们的项目的 package.json
文件中就有三条操作命令了,要注意记得它们分别的作用哦!
之后我们执行命令: npm run build:theme
。
应该可以看到会有一个 lib
文件夹与 .css
文件的生成,这样就完成了 .scss
文件到 .css
文件的转换,并会自动补全 CSS
前缀和压缩了 CSS
(补全功能,你可以尝试使用一些有兼容性的样式试试看,这里就不多说了)。
使用cp-cli移动css文件
生成好了 css
文件后,就完了吗?要如何使用呢?这就需要我们回头想想,我们平常是如何使用 ElementUI
的样式文件的。
我从 官网 上截了一张图,图中可以看到样式的引入,是在 element-ui
文件夹下的,并且它引的是一个 index.css
,我们可以先找到它对应的 .scss
文件看看:
这应该是一个总入口样式文件,它引入所有组件的样式文件。那我们不管三七二十一,也照葫芦画瓢,先来把这个总样式文件 index.scss
创建好:
它内容也简单,我们现在只有一个组件,所以只有一行而已:
@import "./button.scss";
然后你可以再次执行刚才的命令:npm run build:theme
。
可以看到 index.css
就生成完了。
根据上面官网引入的路径,接下来我们只需要把所有的样式文件都移动到根目录下的 lib
文件夹就大功告成了。
这个操作会借用到一个包:npm install cp-cli@1.0.2 -D
。
下完 cp-cli
包后,我们把 theme:build
命令改一改:
"scripts": {
"dev": "webpack-dev-server --config build/webpack.common.js",
"build": "webpack --config build/webpack.common.js",
"build:theme": "gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib lib/theme-chalk"
然后执行命令,观看根目录 lib
文件夹,神奇的事情是不是就发生了?(≧ω≦)(好吧,其实也不是很神奇)
测试组件的样式文件
做了那么多事情,又来到最后一步了,测试阶段,那么如何测试我们写的样式呢?
在上一篇文章 ElementUI源码系列一 - 从零搭建项目架构,项目准备、项目打包、项目测试流程 最后我们介绍了两种测试方式,下面我们用第一种方式 项目打包成本地npm包 来测试组件的样式。
测试详情过程可以去看上一篇文章,就不多介绍啦,总的来说,就是敲命令:
原本项目:
npm run build:theme
npm run build
npm pack
测试项目:
npm install 本地放置tgz包的全路径
npm run serve
(重启项目)
然后在 main.js
引入样式:
import juejinElementUI from 'juejin-element-ui';
import 'juejin-element-ui/lib/theme-chalk/index.css';
Vue.use(juejinElementUI);
最后放个效果图:
用scss编写样式美化button组件
我们稍微来把我们丑出天际的 button
组件美化美化,顺便用用 scss
的本来语法。当然,如果你对 scss
很熟了,你也可以跳过,这不是重点内容。
下面我们会创建如下图红框的一些文件,这是和 ElementUI
一样的目录,它的目录、文件划分还是很合理的,是值得我们参考学习的。
我们对 button.scss
样式文件进行改造:
@import "common/var";
@import "mixins/mixins";
@include b(button) {
background: $--button-default-background-color;
color: $--button-default-font-color;
border-color: $--button-default-border-color;
padding: 10px 16px;
border: 1px solid #ccc;
border-radius: 30px;
var.scss
是整个项目的主题定义:
$--color-white: #FFFFFF !default;
$--button-default-background-color: $--color-white !default;
$--color-text-regular: #606266 !default;
$--button-default-font-color: $--color-text-regular !default;
$--border-color-base: #DCDFE6 !default;
$--button-default-border-color: $--border-color-base !default;
minxins.scss
是存放一些具有相同性质的混入,比如我们下面用到的给每个类名都添加一个 el-
的操作。
@import "function";
@mixin b($block) {
$B: $namespace+'-'+$block !global;
.#{$B} {
@content;
function.scss
文件是存放一些 scss
函数,熟悉 scss
应该就比较了解了。
@import "config";
config.scss
定义了一些变量,有项目的标识 el
,还有编写样式的规范 BEM
,关于 BEM
不了解的小伙伴要赶紧自行去学习一下啦。
$namespace: 'el';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';
最后我们还是再放一张效果图:
ElementUI源码系列一 - 从零搭建项目架构,项目准备、项目打包、项目测试流程
ElementUI源码系列二 - 引入scss,用gulp把scss转成css并补全、压缩,用cp-cli移动目录、文件
ElementUI源码系列三 - 学习gen-cssfile.js文件之自动创建组件的.scss文件与生成index.scss文件内容
ElementUI源码系列四 - 学习new.js文件之自动创建组件目录结构与生成components.json文件内容
ElementUI源码系列五 - 学习build-entry.js文件之自动生成总入口文件index.js内容
ElementUI源码系列六 - 小结
ElementUI源码系列七 - 组件按需引入
ElementUI源码系列八 - 搭建element-ui官方文档之项目的基本框架
ElementUI源码系列九 - 搭建element-ui官方文档之md文件渲染到页面、demo-block组件的实现
至此,本篇文章就写完啦,撒花撒花。
希望本文对你有所帮助,如有任何疑问,期待你的留言哦。
老样子,点赞+评论=你会了,收藏=你精通了。