• webpack-theme-color-replacer动态修改Ant Design Vue主题色


    1. 进入正题,首先我们安装antd
      npm i --save ant-design-vue@next
    2. 在main.js中引入
      1. import Vue from 'vue';
      2. import App from './App.vue';
      3. import router from './router';
      4. import store from './store';
      5. import utils from './config/util.js';
      6. Vue.prototype.$utils = utils;
      7. Vue.prototype.axiosPost = utils.axiosPost; //axios post 请求
      8. Vue.prototype.axiosGet = utils.axiosGet; //axios get 请求
      9. Vue.config.productionTip = false;
      10. import 'ant-design-vue/dist/antd.css'; 这里引入css
      11. //按需引入组件
      12. import {
      13. ConfigProvider,
      14. Layout,
      15. Input,
      16. InputNumber,
      17. Button,
      18. Switch,
      19. Radio,
      20. Checkbox,
      21. Select,
      22. Card,
      23. Form,
      24. Row,
      25. Col,
      26. Modal,
      27. Table,
      28. Tabs,
      29. Icon,
      30. Badge,
      31. Popover,
      32. Dropdown,
      33. List,
      34. Avatar,
      35. Breadcrumb,
      36. Steps,
      37. Spin,
      38. Menu,
      39. Drawer,
      40. Tooltip,
      41. Alert,
      42. Tag,
      43. Divider,
      44. DatePicker,
      45. TimePicker,
      46. Upload,
      47. Progress,
      48. Skeleton,
      49. Popconfirm,
      50. PageHeader,
      51. Result,
      52. Statistic,
      53. Descriptions,
      54. Space,
      55. message,
      56. notification,
      57. } from 'ant-design-vue';
      58. Vue.use(ConfigProvider);
      59. Vue.use(Layout);
      60. Vue.use(Input);
      61. Vue.use(InputNumber);
      62. Vue.use(Button);
      63. Vue.use(Switch);
      64. Vue.use(Radio);
      65. Vue.use(Checkbox);
      66. Vue.use(Select);
      67. Vue.use(Card);
      68. Vue.use(Form);
      69. Vue.use(Row);
      70. Vue.use(Col);
      71. Vue.use(Modal);
      72. Vue.use(Table);
      73. Vue.use(Tabs);
      74. Vue.use(Icon);
      75. Vue.use(Badge);
      76. Vue.use(Popover);
      77. Vue.use(Dropdown);
      78. Vue.use(List);
      79. Vue.use(Avatar);
      80. Vue.use(Breadcrumb);
      81. Vue.use(Steps);
      82. Vue.use(Spin);
      83. Vue.use(Menu);
      84. Vue.use(Drawer);
      85. Vue.use(Tooltip);
      86. Vue.use(Alert);
      87. Vue.use(Tag);
      88. Vue.use(Divider);
      89. Vue.use(DatePicker);
      90. Vue.use(TimePicker);
      91. Vue.use(Upload);
      92. Vue.use(Progress);
      93. Vue.use(Skeleton);
      94. Vue.use(Popconfirm);
      95. Vue.use(PageHeader);
      96. Vue.use(Result);
      97. Vue.use(Statistic);
      98. Vue.use(Descriptions);
      99. Vue.use(Space);
      100. new Vue({
      101. router,
      102. store,
      103. render: h => h(App),
      104. }).$mount('#app');

    3. 然后安装webpack-theme-color-replacer
      npm install webpack-theme-color-replacer
    4.  然后我们在config下创建这3个js文件​​​​​

       

    5.  theme-color-replacer.plugin.config.js文件,代码如下:

      1. const ThemeColorReplacer = require('webpack-theme-color-replacer');
      2. const generate = require('@ant-design/colors/lib/generate').default;
      3. const getAntdSerials = color => {
      4. // 淡化(即less的tint)
      5. const lightens = new Array(9).fill().map((t, i) => {
      6. return ThemeColorReplacer.varyColor.lighten(color, i / 10);
      7. });
      8. const colorPalettes = generate(color);
      9. const rgb = ThemeColorReplacer.varyColor
      10. .toNum3(color.replace('#', ''))
      11. .join(',');
      12. return lightens.concat(colorPalettes).concat(rgb);
      13. };
      14. const themePluginOption = {
      15. fileName: 'css/theme-colors-[contenthash:8].css',
      16. matchColors: getAntdSerials('#1890ff'), // 主色系列
      17. // 改变样式选择器,解决样式覆盖问题
      18. changeSelector(selector) {
      19. switch (selector) {
      20. case '.ant-calendar-today .ant-calendar-date':
      21. return (
      22. ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' +
      23. selector
      24. );
      25. case '.ant-btn:focus,.ant-btn:hover':
      26. return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)';
      27. case '.ant-btn.active,.ant-btn:active':
      28. return '.ant-btn.active:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)';
      29. case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon':
      30. case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon':
      31. return ':not(.ant-steps-item-process)' + selector;
      32. // fixed https://github.com/vueComponent/ant-design-vue-pro/issues/876
      33. case '.ant-steps-item-process .ant-steps-item-icon':
      34. return ':not(.ant-steps-item-custom)' + selector;
      35. 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':
      36. 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':
      37. 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';
      38. case '.ant-menu-horizontal > .ant-menu-item-selected > a':
      39. case '.ant-menu-horizontal>.ant-menu-item-selected>a':
      40. return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item-selected > a';
      41. case '.ant-menu-horizontal > .ant-menu-item > a:hover':
      42. case '.ant-menu-horizontal>.ant-menu-item>a:hover':
      43. return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item > a:hover';
      44. default:
      45. return selector;
      46. }
      47. },
      48. };
      49. const createThemeColorReplacerPlugin = () =>
      50. new ThemeColorReplacer(themePluginOption);
      51. module.exports = createThemeColorReplacerPlugin;
    6. themeColor.js,代码如下:

      1. import client from 'webpack-theme-color-replacer/client';
      2. import generate from '@ant-design/colors/lib/generate';
      3. export default {
      4. getAntdSerials(color) {
      5. // 淡化(即less的tint)
      6. const lightens = new Array(9).fill().map((t, i) => {
      7. return client.varyColor.lighten(color, i / 10);
      8. });
      9. // colorPalette变换得到颜色值
      10. const colorPalettes = generate(color);
      11. const rgb = client.varyColor.toNum3(color.replace('#', '')).join(',');
      12. return lightens.concat(colorPalettes).concat(rgb);
      13. },
      14. changeColor(newColor) {
      15. var options = {
      16. newColors: this.getAntdSerials(newColor), // new colors array, one-to-one corresponde with `matchColors`
      17. changeUrl(cssUrl) {
      18. return `/${cssUrl}`; // while router is not `hash` mode, it needs absolute path
      19. },
      20. };
      21. return client.changer.changeColor(options, Promise);
      22. },
      23. };
    7. themesettingConfig.js,代码如下:
       

      1. import themeColor from './themeColor.js';
      2. import message from 'ant-design-vue/es/message';
      3. import store from '../store';
      4. // color Array
      5. const colorList = [
      6. {
      7. key: '薄暮',
      8. color: '#F5222D',
      9. },
      10. {
      11. key: '火山',
      12. color: '#FA541C',
      13. },
      14. {
      15. key: '日暮',
      16. color: '#FAAD14',
      17. },
      18. {
      19. key: '明青',
      20. color: '#13C2C2',
      21. },
      22. {
      23. key: '极光绿',
      24. color: '#52C41A',
      25. },
      26. {
      27. key: '拂晓蓝(默认)',
      28. color: '#1890FF',
      29. },
      30. {
      31. key: '极客蓝',
      32. color: '#2F54EB',
      33. },
      34. {
      35. key: '酱紫',
      36. color: '#722ED1',
      37. },
      38. ];
      39. // 更新主题方法
      40. const updateTheme = newPrimaryColor => {
      41. console.log('newPrimaryColor:', newPrimaryColor);
      42. store.commit('setprimaryColor', newPrimaryColor);
      43. const hideMessage = message.loading('正在切换主题!', 0);
      44. themeColor.changeColor(newPrimaryColor).finally(() => {
      45. console.log('切换成功');
      46. setTimeout(() => {
      47. hideMessage();
      48. }, 10);
      49. });
      50. };
      51. export { updateTheme, colorList };
    8. 根目录vue.config.js 代码
       

      1. const CompressionPlugin = require('compression-webpack-plugin');
      2. const createThemeColorReplacerPlugin = require('./src/config/theme-color-replacer.plugin.config.js');
      3. module.exports = {
      4. configureWebpack: {
      5. plugins: [
      6. createThemeColorReplacerPlugin() // webpack plugins
      7. ]
      8. }
      9. };
    9. 然后我们新建SettingDrawer.vue组件使用
       
      1. <template>
      2. <div class="setting-drawer">
      3. <a-drawer
      4. width="300"
      5. placement="right"
      6. @close="onClose"
      7. :closable="false"
      8. :visible="visible"
      9. >
      10. <div class="setting-drawer-index-content">
      11. <div :style="{ marginBottom: '24px' }">
      12. <h3 class="setting-drawer-index-title">整体风格设置</h3>
      13. </div>
      14. <div :style="{ marginBottom: '24px' }">
      15. <h3 class="setting-drawer-index-title">主题色</h3>
      16. <div style="height: 20px">
      17. <a-tooltip
      18. class="setting-drawer-theme-color-colorBlock"
      19. v-for="(item, index) in colorList"
      20. :key="index"
      21. >
      22. <template slot="title">
      23. {{ item.key }}
      24. </template>
      25. <a-tag :color="item.color" @click="changeColor(item.color)">
      26. <!-- <a-icon
      27. type="check"
      28. v-if="item.color === primaryColor"
      29. ></a-icon> -->
      30. </a-tag>
      31. </a-tooltip>
      32. </div>
      33. </div>
      34. <a-divider />
      35. <div :style="{ marginBottom: '24px' }">
      36. <h3 class="setting-drawer-index-title">导航模式</h3>
      37. <div>
      38. <a-switch :default-checked="false" @change="changeMode" /> Change
      39. Mode
      40. <br />
      41. <span className="ant-divider" style="margin: 10px" />
      42. <br />
      43. <a-switch :default-checked="false" @change="changeCollapsed" />
      44. Change Theme
      45. </div>
      46. </div>
      47. <a-divider />
      48. </div>
      49. <div class="setting-drawer-index-handle" @click="toggle" slot="handle">
      50. <a-icon type="setting" v-if="!visible" />
      51. <a-icon type="close" v-else />
      52. </div>
      53. </a-drawer>
      54. </div>
      55. </template>
      56. <script>
      57. import { updateTheme, colorList } from '../config/themesettingConfig';
      58. export default {
      59. components: {},
      60. mixins: [],
      61. data() {
      62. return {
      63. visible: false,
      64. colorList,
      65. };
      66. },
      67. watch: {},
      68. mounted() {},
      69. methods: {
      70. changeMode(checked) {
      71. this.$parent.changeMode(checked);
      72. },
      73. changeCollapsed(checked) {
      74. this.$parent.changeCollapsed(checked);
      75. },
      76. showDrawer() {
      77. this.visible = true;
      78. },
      79. onClose() {
      80. this.visible = false;
      81. },
      82. toggle() {
      83. this.visible = !this.visible;
      84. },
      85. changeColor(color) {
      86. console.log('color:', color);
      87. updateTheme(color);
      88. },
      89. },
      90. };
      91. </script>
      92. <style lang="less" >
      93. .setting-drawer-index-content {
      94. .setting-drawer-index-blockChecbox {
      95. display: flex;
      96. .setting-drawer-index-item {
      97. margin-right: 16px;
      98. position: relative;
      99. border-radius: 4px;
      100. cursor: pointer;
      101. img {
      102. width: 48px;
      103. }
      104. .setting-drawer-index-selectIcon {
      105. position: absolute;
      106. top: 0;
      107. right: 0;
      108. width: 100%;
      109. padding-top: 15px;
      110. padding-left: 24px;
      111. height: 100%;
      112. color: #1890ff;
      113. font-size: 14px;
      114. font-weight: 700;
      115. }
      116. }
      117. }
      118. .setting-drawer-theme-color-colorBlock {
      119. width: 20px;
      120. height: 20px;
      121. border-radius: 2px;
      122. float: left;
      123. cursor: pointer;
      124. margin-right: 8px;
      125. padding-left: 0px;
      126. padding-right: 0px;
      127. text-align: center;
      128. color: #fff;
      129. font-weight: 700;
      130. i {
      131. font-size: 14px;
      132. }
      133. }
      134. }
      135. .setting-drawer-index-handle {
      136. position: absolute;
      137. top: 240px;
      138. background: #1890ff;
      139. width: 48px;
      140. height: 48px;
      141. right: 300px;
      142. display: flex;
      143. justify-content: center;
      144. align-items: center;
      145. cursor: pointer;
      146. pointer-events: auto;
      147. z-index: 1001;
      148. text-align: center;
      149. font-size: 16px;
      150. border-radius: 4px 0 0 4px;
      151. i {
      152. color: rgb(255, 255, 255);
      153. font-size: 20px;
      154. }
      155. }
      156. </style>

      引入使用组件即可
  • 相关阅读:
    沁恒 CH32V208(四): CH32V208 网络DHCP示例代码分析
    基于SSM+SpringBoot+MySQL+Vue前后端分离的高校考试管理系统
    Oracle查询最大连接数和当前连接数
    SQLAlchemy 使用封装实例
    kotlin flow sample的用法
    tensor的索引、切片、拼接和压缩等
    el-upload上传组件的动态添加;el-upload动态上传文件;el-upload区分文件是哪个组件上传的。
    中台架构介绍和应用价值
    手画图解 | 关于死锁,面试的一切都在这里了
    详解:飞讯是如何助力集团型制造企业实现数字化转型的
  • 原文地址:https://blog.csdn.net/slow097/article/details/125633774