Vue Ant Design Pro 中定制主题

Posted wangyb56

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue Ant Design Pro 中定制主题相关的知识,希望对你有一定的参考价值。

Vue Ant Design Pro 中定制主题

  • 需求
  • 定制主题
  • 去除“正在切换主题”过渡效果

 

需求

  • 项目要求使用草绿色的主题色
  • 并且去除如下的loading效果

    定制主题

    • 这里可以参照 Ant Design Pro of Vue 官方文档哦
    • 定制方式是使用 less 的 modifyVars 的方式进行覆盖变量
    • 官方文档已经给出了 webpack 、vue cli 2 以及 vue cli 3 三种不同场景下主题的定制方式。这里不再过多赘述
      • vue cli 3 下定制主题方式如下:
        • 项目根目录下修改文件 vue.config.js
        • module.exports = css: loaderOptions: less: lessOptions: modifyVars: \'primary-color\': \'#1DA57A\',\'link-color\': \'#1DA57A\',\'border-radius-base\': \'2px\',,javascriptEnabled: true,,,,,
          ;

去除“正在切换主题”过渡效果

  • Ant Design Pro of Vue 中提供了一个可以在线切换主题和布局的设置抽屉,使用这个抽屉可以很方便的查看更换主题的效果,无需重启脚手架。
  • 真实项目中是需要去掉这个在线主题的定制抽屉的
  • 另一个问题是每次刷新页面是都会出现“正在切换主题”的全局提示
  • 如何去除“正在切换主题”的全局提示呢?
  • 方法很简单:
    • 首先我们需要按照上一节的方法定制好自己的主题哦,不然的话,去除全局提示后主题就还是 ant design 的默认主题哦
    • 上一步之后,就需要打开文件 src/layouts/BasicLayout.vue,大概在137~139行,可以看到这样一段代码:
      if (process.env.NODE_ENV !== \'production\' || process.env.VUE_APP_PREVIEW === \'true\') updateTheme(this.settings.primaryColor)
      
      
      • 注释或删除掉这段代码就可以啦
  • 我们来看看上节中 updateTheme 方法的源码
import client from \'webpack-theme-color-replacer/client\'
import generate from \'@ant-design/colors/lib/generate\'
import  message  from \'ant-design-vue\'export const themeColor = getAntdSerials (color) // 淡化(即less的tint)const lightens = new Array(9).fill().map((t, i) => return client.varyColor.lighten(color, i / 10))// colorPalette 变换得到颜色值const colorPalettes = generate(color)const rgb = client.varyColor.toNum3(color.replace(\'#\', \'\')).join(\',\')return lightens.concat(colorPalettes).concat(rgb),changeColor (newColor) const options = newColors: this.getAntdSerials(newColor), // new colors array, one-to-one corresponde with `matchColors`changeUrl (cssUrl) return `/$cssUrl` // while router is not `hash` mode, it needs absolute pathreturn client.changer.changeColor(options, Promise)
export const updateTheme = newPrimaryColor => const hideMessage = message.loading(\'正在切换主题\', 0)themeColor.changeColor(newPrimaryColor).then(r => hideMessage())
export const updateColorWeak = colorWeak => // document.body.className = colorWeak ? \'colorWeak\' : \'\';const app = document.body.querySelector(\'#app\')colorWeak ? app.classList.add(\'colorWeak\') : app.classList.remove(\'colorWeak\')
  • 很明显,出现“正在切换主题”全局提示的罪魁祸首就是 updateTheme 方法里面的 hideMessage 方法
  • 其实之前想到的另一个方法就是直接使用 themeColor 的 changeColor 方法,而不是使用 updateTheme
  • 但不幸的是,这里虽然 export 了 themeColor,但 pro-layout 的 index.js 里面却没有 export 出去,所以项目中我们也就无从用起了 ε=(´ο`*)))唉
  •  

使用React+Umi+Ant Design Pro实现生产环境动态切换主题,支持暗黑主题

  投入前端开发也有1年的时间了,我还是很菜.在开发中还是很多技巧以及经验不够,写文章也是文笔不行,不过好在写的内容意思大概都能看懂.这次就来介绍一下我在开发过程中遇到的一些问题以及处理技巧.

  两月前刚开始试用umi这个React的框架,使用AntD Pro创建好项目后,着实熟悉了几天,不过熟悉这个框架后,就觉得阿里的大佬还是牛.佩服.

  事情是这样的,我们能够在AndD Pro的在线预览上看到能够动态切换主题.而实际拉下来的模板中却没有这个功能.我就开始了对比源码.

  算了,先上一下项目目录结构吧,不然说起来不知所云.被我精简后的项目结构大概就是这样.删掉了,很多用于语法验证的ESLINT库等,使用VS插件提供支持,这么做的好处就是写代码的时候就能进行验证,格式化,而不是编译和提交的时候去搞这一堆事情.

  技术图片

 

回到主题,我发现源码中的layouts中的BasicLayout中缺少了,SettingDrawer的引用.所以这里我们自己把他加上,并放在页面中

技术图片技术图片

 

在model中的setting中使用默认的切换主题的代码就能实现动态切换主题了.

以为到这里就完了?

嘿嘿,其实并没有.

你会发现这个东西,不管你怎么切换主题,界面是没有反应的,只有默认主题,这.....心里肯定是崩溃的.

所以我们还需要做一些处理.

首先按照官方的默认主题配置中写好想要的默认主题.就是这个default.config文件.名字可能和官方不太一样,因为我自己这个项目我改了很多文件名的.

技术图片

 

这个文件的作用就是告诉umi框架默认主题就是这个样的,

然后我们去命令行工具添加几个好东西.

首先我们先添加

umi-plugin-antd-theme
这个插件.对,没错,就这一个好东西??可以使用npm命令,或者yarn命令进行添加.从名字我们可以发现这个库是umi的一个插件.
所以接下来就是配置这个插件.通过antd官方的例子我们可以看到支持的主题整成了一个单独的主题样式文件.
在我这里就是theme.config文件.
我这里贴一下官方案例中文件的内容
export const themeConfig = {
  theme: [
    { key: ‘dark‘, fileName: ‘dark.css‘, theme: ‘dark‘ },
    { key: ‘dust‘, fileName: ‘dust.css‘, modifyVars: { ‘@primary-color‘: ‘#F5222D‘ } },
    { key: ‘volcano‘, fileName: ‘volcano.css‘, modifyVars: { ‘@primary-color‘: ‘#FA541C‘ } },
    { key: ‘sunset‘, fileName: ‘sunset.css‘, modifyVars: { ‘@primary-color‘: ‘#FAAD14‘ } },
    { key: ‘cyan‘, fileName: ‘cyan.css‘, modifyVars: { ‘@primary-color‘: ‘#13C2C2‘ } },
    { key: ‘green‘, fileName: ‘green.css‘, modifyVars: { ‘@primary-color‘: ‘#52C41A‘ } },
    { key: ‘geekblue‘, fileName: ‘geekblue.css‘, modifyVars: { ‘@primary-color‘: ‘#2F54EB‘ } },
    { key: ‘purple‘, fileName: ‘purple.css‘, modifyVars: { ‘@primary-color‘: ‘#722ED1‘ } },

    { key: ‘dust‘, theme: ‘dark‘, fileName: ‘dark-dust.css‘, modifyVars: { ‘@primary-color‘: ‘#F5222D‘ } },
    { key: ‘volcano‘, theme: ‘dark‘, fileName: ‘dark-volcano.css‘, modifyVars: { ‘@primary-color‘: ‘#FA541C‘ } },
    { key: ‘sunset‘, theme: ‘dark‘, fileName: ‘dark-sunset.css‘, modifyVars: { ‘@primary-color‘: ‘#FAAD14‘ } },
    { key: ‘cyan‘, theme: ‘dark‘, fileName: ‘dark-cyan.css‘, modifyVars: { ‘@primary-color‘: ‘#13C2C2‘ } },
    { key: ‘green‘, theme: ‘dark‘, fileName: ‘dark-green.css‘, modifyVars: { ‘@primary-color‘: ‘#52C41A‘ } },
    { key: ‘geekblue‘, theme: ‘dark‘, fileName: ‘dark-geekblue.css‘, modifyVars: { ‘@primary-color‘: ‘#2F54EB‘ } },
    { key: ‘purple‘, theme: ‘dark‘, fileName: ‘dark-purple.css‘, modifyVars: { ‘@primary-color‘: ‘#722ED1‘ } }
  ],
  min: true, // 是否压缩css
  isModule: true, // css module
  ignoreAntd: false, // 忽略 antd 的依赖
  ignoreProLayout: false, // 忽略 pro-layout
  cache: true // 不使用缓存
};

 

写好这个文件后,就可以在config中配置主题了.接下来我直接贴图.

技术图片

 

 

 

特别注意的地方就是这几个箭头处,首先导入主题文件,然后配置umi插件使用主题配置,然后特别注意的就是不再配置umi默认的那个webpack的主题了,给他一个空对象就行了.
然后我们编译项目,发布后,在线浏览项目,发现主题已经可以正常切换了.这里再次膜拜一下大佬们的贡献.
 
然鹅......我们点一下浏览器的刷新按钮就会发现,主题又恢复默认了. ??简直是....................
 
所以接下来我们就得研究一下为什么主题又变成了默认.
 
首先我们就看到SettingDrawer这个组件调用的方法,setting/changeSetting 所以我们就去model中的setting文件看看是什么原因,发现,这个地方无论你怎么改主题,取得主题都是默认配置.
原来是读取的总是默认配置,这下就知道为啥了.所以我们对这个model进行一下改造直接贴出我的代码.
import { defaultConfig } from ‘../../config/default.config‘;

const updateColorWeak = colorWeak => {
  const root = document.getElementById(‘root‘);
  if (root) {
    root.className = colorWeak ? ‘colorWeak‘ : ‘‘;
  }
};

const themeData = JSON.parse(localStorage.getItem(‘smart-theme‘));

const SettingModel = {
  namespace: ‘settings‘,
  state: themeData || defaultConfig,
  reducers: {
    changeSetting(state = defaultConfig, { payload }) {
      const { colorWeak, contentWidth } = payload;
      if (state.contentWidth !== contentWidth && window.dispatchEvent) {
        window.dispatchEvent(new Event(‘resize‘));
      }
      updateColorWeak(!!colorWeak);
      localStorage.setItem(‘smart-theme‘, JSON.stringify({ ...state, ...payload }));
      return { ...state, ...payload };
    }
  }
};
export default SettingModel;

我的改动实际上就是如图的三个地方,首先在修改后返回样式之前将样式存到localStorage,由于他是个对象,所以需要转成字符串.然后再取出来并且转成字符串,以后在每一次state返回的时候,默认返回localStrage中的配置信息,若是不存在就返回默认的.

技术图片

 

 

到这里我们就能愉快的进行在生产环境切换主题了.

 ヾ(≧▽≦*)oヾ(≧▽≦*)oヾ(≧▽≦*)o 至此,我们的在线主题切换就全部完成了,结合官方默认的主题就能支持暗黑模式了.

然鹅......你以为完了???其实还没有,因为还有一个问题.官方的默认暗黑主题,表格被选中后的背景色还是白色.那么你在黑色的主题下,用白色的背景,效果就是下面这样

 

 技术图片

 

 显示效果是不是很棒,完全不知道数据是什么.而且亮瞎眼.??

所以我们还需要对官方提供的主题配置做点手脚.

那就是在所有的黑色主题的配置中加入自定义的配置 

‘@table-selected-row-bg‘: ‘#30303d !important‘
用来修改默认的选中后的背景色.这里加一个!important表示强制使用.
接下来我贴一下我的theme.config文件的内容.
export const themeConfig = {
  theme: [
    { key: ‘dust‘, fileName: ‘dust.css‘, modifyVars: { ‘@primary-color‘: ‘#F5222D‘ } },
    { key: ‘volcano‘, fileName: ‘volcano.css‘, modifyVars: { ‘@primary-color‘: ‘#FA541C‘ } },
    { key: ‘sunset‘, fileName: ‘sunset.css‘, modifyVars: { ‘@primary-color‘: ‘#FAAD14‘ } },
    { key: ‘cyan‘, fileName: ‘cyan.css‘, modifyVars: { ‘@primary-color‘: ‘#13C2C2‘ } },
    { key: ‘green‘, fileName: ‘green.css‘, modifyVars: { ‘@primary-color‘: ‘#52C41A‘ } },
    { key: ‘geekblue‘, fileName: ‘geekblue.css‘, modifyVars: { ‘@primary-color‘: ‘#2F54EB‘ } },
    { key: ‘purple‘, fileName: ‘purple.css‘, modifyVars: { ‘@primary-color‘: ‘#722ED1‘ } },
    { key: ‘dark‘, fileName: ‘dark.css‘, theme: ‘dark‘, modifyVars: { ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘dust‘, theme: ‘dark‘, fileName: ‘dark-dust.css‘, modifyVars: { ‘@primary-color‘: ‘#F5222D‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘volcano‘, theme: ‘dark‘, fileName: ‘dark-volcano.css‘, modifyVars: { ‘@primary-color‘: ‘#FA541C‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘sunset‘, theme: ‘dark‘, fileName: ‘dark-sunset.css‘, modifyVars: { ‘@primary-color‘: ‘#FAAD14‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘cyan‘, theme: ‘dark‘, fileName: ‘dark-cyan.css‘, modifyVars: { ‘@primary-color‘: ‘#13C2C2‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘green‘, theme: ‘dark‘, fileName: ‘dark-green.css‘, modifyVars: { ‘@primary-color‘: ‘#52C41A‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘geekblue‘, theme: ‘dark‘, fileName: ‘dark-geekblue.css‘, modifyVars: { ‘@primary-color‘: ‘#2F54EB‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } },
    { key: ‘purple‘, theme: ‘dark‘, fileName: ‘dark-purple.css‘, modifyVars: { ‘@primary-color‘: ‘#722ED1‘, ‘@table-selected-row-bg‘: ‘#30303d !important‘ } }
  ],
  min: true, // 是否压缩css
  isModule: true, // css module
  ignoreAntd: false, // 忽略 antd 的依赖
  ignoreProLayout: false, // 忽略 pro-layout
  cache: true // 不使用缓存
};

经过以上的一系列步骤和调整,终于能过够正常的在线切换主题,并且刷新也不会造成恢复默认了.

接下来是一个效果图.

 

 技术图片

以上是关于Vue Ant Design Pro 中定制主题的主要内容,如果未能解决你的问题,请参考以下文章

Ant-design-vue定制主题色

Ant-design-vue定制主题色

Ant Design Pro Vue使用心得

使用React+Umi+Ant Design Pro实现生产环境动态切换主题,支持暗黑主题

Vue 开发实战实战篇 # 26:Ant Design Pro介绍

Ant Design Pro V5 包含演示效果创建方法