赞
踩
有很多解决方案,例如antd-theme-webpack-plugin,但是尝试失败,antdv 2.2.8版本与之前的路径与源码有所不同,直到找到webpack-theme-color-replacer的文章取经之后踩坑实现了效果
项目使用的是Vue3+typescript
npm i --save ant-design-vue@next
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App);
// 引入antdv
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.less'; // 这里引入less文件
app.use(store).use(router).use(Antd).mount('#app')
npm install webpack-theme-color-replacer
// theme-color-replacer.plugin.config.js // ant desgin vue 配置 // 引入webpack-theme-color-replacer const ThemeColorReplacer = require('webpack-theme-color-replacer') // 引入@ant-design 的 根据传入颜色 变换得到颜色值 方法 const generate = require('@ant-design/colors/dist/index.js') // 引入默认主题配置 这里是antdv 的可以去官网查看(这里踩坑了,直接在matchColors: getAntdSerials("#1890ff")写入antdv的主题色#1890ff即可) // const ThemeObj = require('ant-design-vue/dist/antd.less') const getAntdSerials = (color) => { // 淡化(即less的tint) const lightens = new Array(9).fill().map((t, i) => { return ThemeColorReplacer.varyColor.lighten(color, i / 10) }) const colorPalettes = generate.generate(color) const rgb = ThemeColorReplacer.varyColor.toNum3(color.replace('#', '')).join(',') return lightens.concat(colorPalettes).concat(rgb) } const themePluginOption = { fileName: 'css/theme-colors-[contenthash:8].css', // 输出css文件名 支持[contenthash] 与 [hash] matchColors: getAntdSerials("#1890ff"), // 主色系列 这里需要配置默认主题色,切换的时候是根据这里配置颜色值 去获取颜色来替换的 // 改变样式选择器,解决样式覆盖问题 changeSelector (selector) { switch (selector) { case '.ant-calendar-today .ant-calendar-date': return ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' + selector case '.ant-btn:focus,.ant-btn:hover': return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)' case '.ant-btn.active,.ant-btn:active': return '.ant-btn.active:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)' case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon': case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon': return ':not(.ant-steps-item-process)' + selector case '.ant-menu-horizontal>.ant-menu-item-active,.ant-menu-horizontal>.ant-menu-item-open,.ant-menu-horizontal>.ant-menu-item-selected,.ant-menu-horizontal>.ant-menu-item:hover,.ant-menu-horizontal>.ant-menu-submenu-active,.ant-menu-horizontal>.ant-menu-submenu-open,.ant-menu-horizontal>.ant-menu-submenu-selected,.ant-menu-horizontal>.ant-menu-submenu:hover': case '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal > .ant-menu-submenu-selected,.ant-menu-horizontal > .ant-menu-submenu:hover': return '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover' case '.ant-menu-horizontal > .ant-menu-item-selected > a': case '.ant-menu-horizontal>.ant-menu-item-selected>a': return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item-selected > a' case '.ant-menu-horizontal > .ant-menu-item > a:hover': case '.ant-menu-horizontal>.ant-menu-item>a:hover': return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item > a:hover' default : return selector } } } const createThemeColorReplacerPlugin = () => new ThemeColorReplacer(themePluginOption) module.exports = createThemeColorReplacerPlugin
创建themeColor.js,代码如下:
// themeColor.js import client from 'webpack-theme-color-replacer/client' import {generate} from '@ant-design/colors/dist/index.js' export default { getAntdSerials (color) { // 淡化(即less的tint) const lightens = new Array(9).fill().map((t, i) => { return client.varyColor.lighten(color, i / 10) }) const colorPalettes = generate(color) const rgb = client.varyColor.toNum3(color.replace('#', '')).join(',') return lightens.concat(colorPalettes).concat(rgb) }, // 运行时更改主题颜色 changeColor (newColor) { var options = { newColors: this.getAntdSerials(newColor), // 新颜色数组,与" matchColors"一一对应 changeUrl (cssUrl) { return `/${cssUrl}` // while router is not `hash` mode, it needs absolute path } // appendToEl: 'head', //optional. The element selector for appending child with `<style>`, default is 'body'. Using `appendToEl: 'body'` can make the css priority higher than any css in <head> } return client.changer.changeColor(options, Promise) } }
创建settingConfig.js,代码如下:
import themeColor from './themeColor.js' import message from 'ant-design-vue/es/message' // color Array const colorList = [ { key: '薄暮', color: '#F5222D' }, { key: '火山', color: '#FA541C' }, { key: '日暮', color: '#FAAD14' }, { key: '明青', color: '#13C2C2' }, { key: '极光绿', color: '#52C41A' }, { key: '拂晓蓝(默认)', color: '#1890FF' }, { key: '极客蓝', color: '#2F54EB' }, { key: '酱紫', color: '#722ED1' } ] // 更新主题方法 const updateTheme = newPrimaryColor => { // 这里可以写上切换loading 或者 提示等等 const hideMessage = message.loading('正在切换主题!', 0) themeColor.changeColor(newPrimaryColor).finally(() => { // 切换成功后回调方法 这里可以关闭loading 或者 提示等等 setTimeout(() => { hideMessage() }, 10) }) } export { updateTheme, colorList }
const createThemeColorReplacerPlugin = require('./src/theme/theme-color-replacer.plugin.config')
module.exports = {
css: {
loaderOptions: {
less: {
javascriptEnabled: true // 这里需要为true,否则引入的antdv的less文件会报错
}
}
},
configureWebpack: {
plugins: [
createThemeColorReplacerPlugin() // webpack plugins
]
}
};
通过updateTheme方法传入颜色修改主题色
declare module ‘*.js’
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。