ant-design-vue 运行时切换主题

647 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。

1 . 安装antd-theme-generaor

npm i antd-theme-generator -D

配置.babelrc

{
  "plugins": [
    [
      "import",
      {
        "libraryName": "ant-design-vue",
        "libraryDirectory": "es",
        "style": true
      }
    ] // `style: true` 会加载 less 文件
  ]
}

配置vue.config.js

css: {
    loaderOptions: {
      less: {
        modifyVars: {
          // 'primary-color': '#1DA57A',
          // 'link-color': '#1DA57A',
          // 'border-radius-base': '2px'
        },
        javascriptEnabled: true,
      },
    },
  },

2. 在根目录创建color.js,这个脚本执行后会生成能实现动态主题切换的less文件,输出到public/color.less文件中。

const path = require("path");
const { generateTheme } = require("antd-theme-generator");

const options = {
  antDir: path.join(__dirname, "./node_modules/ant-design-vue"),
  stylesDir: path.join(__dirname, "./src/styles/theme"),
  varFile: path.join(__dirname, "./src/styles/theme/variables.less"),
  mainLessFile: path.join(__dirname, "./src/styles/theme/main.less"),
  outputFilePath: path.join(__dirname, "./public/color.less"),
  themeVariables: [
    "@primary-color",
    "@layout-header-background",
    "@table-header-sort-active-bg",
  ],
};

generateTheme(options)
  .then(() => {
    console.log("Theme generated successfully");
  })
  .catch((error) => {
    console.log("Error", error);
  });

3. 在src/styles/theme目录下,创建variables.less main.less themes.ts文件

image.png

  • varibales.less中引入default.less,给我们要动态切换的less变量赋初始值:
// 引入官方默认的样式less 
@import '../../../node_modules/ant-design-vue/lib/style/themes/default.less';
// 添加了如下代码,解决报错问题NameError: variable @table-header-sort-active-bg is undefined
@table-header-sort-active-bg: darken(@table-header-bg, 3%);
  • main.less内容为空就可以。
  • themes.ts文件中存放需要不同主题的变量
interface ThemeItem {
  [name: string]: string;
}
export interface ThemesType {
  [name: string]: ThemeItem;
}
const themes: ThemesType = {
  green: {
    "@primary-color": "#00C4B8",
    "@layout-header-background": "#1FE8A7",
  },
  blue: {
    "@primary-color": "#337DFF",
    "@layout-header-background": "#1E1E1E",
  },
  red: {
    "@primary-color": "#C01D25",
    "@layout-header-background": "#6C120C",
  },
};

export default themes;

4. 在index.html文件中引用color.less

  <link rel="stylesheet/less" type="text/css" href="/color.less?v=%RANDOM%" />
  <script src="https://cdn.bootcss.com/less.js/2.7.3/less.min.js"></script>

5. 通过window.less.modifyVars切换主题

import themes from "@/styles/theme/themes";
function changeTheme(theme: string) {
  (window as any).less
    .modifyVars(themes[theme])
    .then(() => {})
    .catch((error: any) => {
      console.log(error);
    });
}
export default changeTheme;

6. 配置

对于公共的样式调整,比如字体调整,变量放在vue.config.js文件中的modifyVars即可

image.png

对于不同主题的样式调整,需要配置两个地方

  1. color.js中配置相应的变量; image.png
  2. 在theme.ts中,为不同主题配置不同的样式 image.png