当前位置:   article > 正文

webpack-theme-color-replacer动态修改Ant Design Vue主题色_ant切换主题颜色不生效 使用webpack

ant切换主题颜色不生效 使用webpack

度娘出不来效果,尝试总有一点小问题

有很多解决方案,例如antd-theme-webpack-plugin,但是尝试失败,antdv 2.2.8版本与之前的路径与源码有所不同,直到找到webpack-theme-color-replacer的文章取经之后踩坑实现了效果

项目使用的是Vue3+typescript

  1. 进入正题,首先我们安装antdv

npm i --save ant-design-vue@next

  1. 在main.js中引入
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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. 然后安装webpack-theme-color-replacer

npm install webpack-theme-color-replacer

  1. 然后我们在src下创建theme文件夹
    在这里插入图片描述
    然后创建theme-color-replacer.plugin.config.js文件,代码如下:
// 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

创建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)
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

创建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 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  1. 在项目根目录新建vue.config.js
    在这里插入图片描述
    代码如下:
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
    ]
  }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 然后我们新建theme.vue

通过updateTheme方法传入颜色修改主题色

在这里插入图片描述

  1. 因为使用的是typescript,所以需要在shims-vue.d.ts中加入下面代码

declare module ‘*.js’

在这里插入图片描述

  1. 然后看效果吧
    在这里插入图片描述
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/638106
推荐阅读
相关标签
  

闽ICP备14008679号