::: tip
本文介绍工作中碰到的需求,需要基于vue2、ant-design-vue@1版本和less实现使用了ant-design-vue组件库的项目在线配置主题。其中核心就是html支持直接引入stylesheet/less ,可以使用less.modifyVars修改变量动态编译。
:::
项目依赖
- ant-design-vue@1.7.8
- vue@2.7.13
- vuex@3.6.2
- less@3.13.1
- less-loader@4.1.0
整体配置的地方汇总
本文涉及到需要修改的文件汇总如下:
脚手架默认生成的public下有index.html,同级新建目录libs,libs下放文件color.less 和从node_modules/less包下copy出来的less.js。
color.less里面可以放ant-design-vue支持的所有less变量,默认可以设置为自己想要的一套默认主题色系。
vue.config.js配置
首先需要在vue.config.js配置css的loaderOptions,具体配置如下:
js
const path = require('path')
module.exports = {
css: {
loaderOptions: {
less: {
javascriptEnable: true,
javascriptEnabledInStrictMode: true, // 严格模式支持在css中写js
modifyVars: {
hack: `true; @import "${path.join(__dirname, 'public/libs/color.less')}"`
}
}
}
}
}
main.js不需要改动,正常全局注册ant-design-vue和引入ant-design-vue/dist/antd.less样式文件就行。
开始配置
准备可以输入或者修改色值的容器,颜色改变之后,可以存储local Store 、vuex等,之后执行如下逻辑:
js
let lessNodesAppended = false
const buildIt = function (primaryColor) {
// 正确判定less是否已经加载,并且less.modifyVars可用
if (!window.less || !window.less.modifyVars) return
window.less.modifyVars({
'@primary-color': primaryColor
}).then(() => {
console.log('成功')
}).catch(err => {
console.error('失败:', err)
})
}
const UpdateTheme = function (primaryColor) {
// 生产环境不编译less
if (process.env.NODE_ENV === 'production') return
if (!primaryColor) return
// 判断是否已经编译过
if (!lessNodesAppended) {
// 如果没有编译过,开始插入less.js和color.less
const lessStyleNode = document.createElement('link')
const lessConfigNode = document.createElement('script')
const lessScriptNode = document.createElement('script')
lessStyleNode.setAttribute('rel', 'stylesheet/less')
lessStyleNode.setAttribute('href', '/libs/color.less')
lessConfigNode.innerHTML = `
window.less = {
async: true,
env: 'production',
javascriptEnabled: true
}
`
lessScriptNode.src = '/libs/less.js'
lessScriptNode.async = true
lessScriptNode.onload = () => {
buildIt(primaryColor)
lessScriptNode.onload = null
}
document.body.appendChild(lessStyleNode)
document.body.appendChild(lessConfigNode)
document.body.appendChild(lessScriptNode)
lessNodesAppended = true
} else {
buildIt(primaryColor)
}
}
执行成功之后,之前定义的color.less文件会重新编译为一份新的css,全站主题色就会变成改之后的颜色,编译完成之后结果如下: