不知道大家是不是很久没搞Vue2相关的项目了,公司的老项目是用 Vue2 开发的,UI框架用的是 ant-deisgn-vue。
但是,ant-design-vue其实只有1.x版本支持Vue2,想要升2.x版本都得升Vue3。
大家都知道问题出在哪儿,但是没有任何一个人敢出手解决。问题的原因其实懂得都懂~
需求是固定的,要求这套系统存在多种色系(皮肤),所以基于 1.x 版本开发换肤功能成为必然。
解决方案1:样式覆盖
一开始使用的方案就是传统的CSS样式覆盖,这个方案最直观,也最好用。
但是 ant-deisgn 的 class 太多了,简直是多如牛毛的多。
单纯的CSS样式覆盖很难改全,在实际修改的过程中会发现class本身有颜色,class:hover也是有颜色的,class:foucs也是有颜色的,甚至active的颜色都不一样。
虽然工作量巨大,但是改了将近一个月以后也基本上覆盖全了。
这时候发现一个问题,想改第二版太难了。
开发的时候没有针对皮肤颜色抽离变量,导致所有的颜色都是分散在各个Class中的。
很容易出现改漏,改坏的情况。
最关键的是某个样式在某个页面上是隐藏的,改造过程中很容易就遗漏了。
解决方案2:Layout切换
后来采用MainLayout组件切换的方式,多套主题存在多个MainLayout组件,将皮肤以插件的形式进行控制。
其实核心是不变的,还是CSS样式覆盖。
整体能够在系统内达到了切换皮肤的目的,但之前Class太多的问题没有解决。
虽然通过 less 变量对颜色进行了抽离,能够比较方便的进行颜色的修改了。
但是组件引用颜色变量以后,出现了特殊需求的情况。
比如 Tab 组件的背景色和 Button 组件的背景色共用 @bg 这个变量。
现在新需求是这俩颜色要求不一样,这时候就比较难改了。
尤其是出现CSS权重 !important 的时候,简直是无解。
解决方案3:modifyVars颜色覆盖
之前也没仔细看过 ant-deisgn 的官方,现在这个事儿翻出来以后又重新去官方上查。
发现官方其实已经给了定制主题的方案,可以通过使用 less 变量的覆盖来进行非侵入式的修改UI框架颜色。
先安装 less 和 less-loader,然后在 vue-cli 中找到 vue.config.js 配置文件。
增加下面的代码:
js
// 这是 less-loader@6.x 以上的版本
module.exports = {
css: {
loaderOptions: {
less: {
lessOptions: {
// less-loader@5.x 没有lessOptions
modifyVars: {
'primary-color': '#1DA57A',
'link-color': '#1DA57A',
'border-radius-base': '2px',
},
javascriptEnabled: true,
},
},
},
},
};
modifyVars 中的属性可以去 node_modules/ant-design-vue/components/style/themes/default.less 中找到。
这里面几乎覆盖的整个 ant-design 所有颜色和样式。
如果你需要主题效果,可以在 .env 中创建一个变量 VUE_APP_THEME='light',然后创建文件 src/theme/light.js
js
module.exports = {
'primary-color': '#1DA57A',
'link-color': '#1DA57A',
'border-radius-base': '2px',
}
需要几个主题,就创建几个 js 文件,也可以将颜色以变量的形式进一步抽离。
在 vue.config.js 中可以通过判断 .env 中的变量来切换主题。
js
let themeVars;
const THEME = process.env.VUE_APP_THEME;
if (THEME === 'light') {
themeVars = require('./src/theme/light.js')
} else {
themeVars = require('./src/theme/default.js')
}
module.exports = {
css: {
loaderOptions: {
less: {
lessOptions: {
modifyVars: themeVars,
javascriptEnabled: true,
},
},
},
},
};
最麻烦的一点在于,记得每次修改完以后重启项目,否则不生效。
最后提醒一句:在 light.js 中定义的颜色变量其实也可以在别的 less 文件中访问到。