【Vue 开发实战】实战篇 # 42:如何定制主题及动态切换主题
并注入到您的 index.html 文件中,以便您可以在浏览器中更改 Ant Design 特定的颜色主题。此脚本生成颜色特定的样式/更少文件,您可以使用该文件在浏览器中动态更改主题。我们动态修改一下,在控制台将主题色改为粉色的,执行下面代码。这个 webpack 插件用于生成特定颜色的。但是这个我们不安装该依赖,主要原因还是版本。报错,有兴趣的可以看看我刚刚提到的文章。【Vue 开发实战】学习笔
说明
【Vue 开发实战】学习笔记。
vuecli3 配置
module.exports = {
css: {
loaderOptions: {
less: {
modifyVars: {
'primary-color': '#1DA57A',
},
javascriptEnabled: true
},
}
},
}
我们可以修改一下写法
<style lang="less" src="./index.less"></style>
引入下面的 index.less
就行
@import "~ant-design-vue/lib/style/themes/default.less";
.kaimo-handle {
position: absolute;
top: 240px;
right: 300px;
width: 48px;
height: 48px;
background-color: @primary-color;
color: #fff;
font-size: 20px;
text-align: center;
line-height: 48px;
border-radius: 3px 0 0 3px;
}
在线动态编译
如果你有报错可以参考我遇到的问题文章链接:Ant design vue动态主题切换报错Error LessError: Cannot find module ‘antd/lib/style/themes/default.less
这里我们使用 antd-theme-webpack-plugin
这个 webpack 插件用于生成特定颜色的 less/css
并注入到您的 index.html 文件中,以便您可以在浏览器中更改 Ant Design 特定的颜色主题。
具体的配置看文档就行。
但是这个我们不安装该依赖,主要原因还是版本1.3.9
报错,有兴趣的可以看看我刚刚提到的文章。
1、新建插件
我们新建一个 ant-design-vue-pro\webpack-plugins\antd-theme-webpack-plugin.js
插件:里面的代码直接复制 antd-theme-webpack-plugin
的代码。
// https://github.com/mzohaibqc/antd-theme-webpack-plugin/blob/master/index.js
const { generateTheme } = require("antd-theme-generator");
const webpack = require("webpack");
const { RawSource } = webpack.sources || require("webpack-sources");
const path = require("path");
class AntDesignThemePlugin {
constructor(options) {
const defaultOptions = {
varFile: path.join(__dirname, "../../src/styles/variables.less"),
antDir: path.join(__dirname, "../../node_modules/antd"),
stylesDir: path.join(__dirname, "../../src/styles/antd"),
themeVariables: ["@primary-color"],
indexFileName: "index.html",
generateOnce: false,
lessUrl: "https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js",
publicPath: "",
};
this.options = Object.assign(defaultOptions, options);
this.generated = false;
this.version = webpack.version;
}
apply(compiler) {
const pluginName = "AntDesignThemePlugin";
if (this.version.startsWith("5.")) {
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
compilation.hooks.processAssets.tapAsync(
{
name: pluginName,
stage:
webpack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
},
(assets, callback) =>
this.addAssets(compilation, assets, callback)
);
});
} else {
compiler.hooks.emit.tapAsync(pluginName, (compilation, callback) =>
this.addAssets(compilation, compilation.assets, callback)
);
}
}
addAssets(compilation, assets, callback) {
this.generateIndexContent(assets, compilation);
if (this.options.generateOnce && this.colors) {
this.generateColorStylesheet(compilation, this.colors);
return callback();
}
generateTheme(this.options)
.then((css) => {
if (this.options.generateOnce) {
this.colors = css;
}
this.generateColorStylesheet(compilation, css);
callback();
})
.catch((err) => {
callback(err);
});
}
generateIndexContent(assets, compilation) {
if (
this.options.indexFileName &&
this.options.indexFileName in assets
) {
const index = assets[this.options.indexFileName];
let content = index.source();
if (!content.match(/\/color\.less/g)) {
const less = `
<link rel="stylesheet/less" type="text/css" href="${this.options.publicPath}/color.less" />
<script>
window.less = {
async: false,
env: 'production'
};
</script>
<script type="text/javascript" src="${this.options.lessUrl}"></script>
`;
const updatedContent = content
.replace(less, "")
.replace(/<body>/gi, `<body>${less}`);
if (this.version.startsWith("5.")) {
compilation.updateAsset(
this.options.indexFileName,
new RawSource(updatedContent),
{ size: updatedContent.length }
);
return;
}
index.source = () => updatedContent;
index.size = () => updatedContent.length;
}
}
}
generateColorStylesheet(compilation, source) {
if (this.version.startsWith("5.")) {
compilation.emitAsset("color.less", new RawSource(source), {
size: source.length,
});
return;
}
compilation.assets["color.less"] = {
source: () => source,
size: () => source.length,
};
}
}
module.exports = AntDesignThemePlugin;
2、安装依赖
然后安装 antd-theme-webpack-plugin
需要的依赖 antd-theme-generator
此脚本生成颜色特定的样式/更少文件,您可以使用该文件在浏览器中动态更改主题
npm install antd-theme-generator@1.2.3 -D
具体可以看文档: https://github.com/mzohaibqc/antd-theme-generator
3、配置 vue.config.js
const path = require("path");
const AntDesignThemePlugin = require('./webpack-plugins/antd-theme-webpack-plugin');
const options = {
antDir: path.join(__dirname, './node_modules/ant-design-vue'),
stylesDir: path.join(__dirname, './src'),
varFile: path.join(__dirname, './src/assets/styles/theme/variables.less'),
themeVariables: ['@primary-color'],
generateOnce: false
}
const themePlugin = new AntDesignThemePlugin(options);
module.exports = {
lintOnSave: false,
css: {
loaderOptions: {
less: {
modifyVars: {
'primary-color': '#1DA57A',
},
javascriptEnabled: true
},
}
},
chainWebpack: config => {
const svgRule = config.module.rule('svg');
// 清除已有的所有 loader。
// 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。
svgRule.uses.clear();
// 添加要替换的 loader
svgRule.use('vue-svg-loader').loader('vue-svg-loader');
},
configureWebpack: {
plugins: [ themePlugin ]
},
devServer: {
proxy: {
// '@(/api)': { target: 'http://localhost:3000',
'/api': {
target: 'http://localhost:8080',
bypass: function (req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
} else if(process.env.MOCK !== "none") {
// 将请求url转为文件名
const name = req.path.split("/api/")[1].split("/").join("_");
const mock = require(`./mock/${name}`);
const result = mock(req.method);
// 需要清除缓存
delete require.cache[require.resolve(`./mock/${name}`)];
return res.send(result);
}
},
},
},
},
}
4、添加 variables.less
新建 ant-design-vue-pro\src\assets\styles\theme\variables.less
@import "~ant-design-vue/lib/style/themes/default.less";
关于 ~
的使用可以查看:https://www.npmjs.com/package/less-loader#webpack-resolver
5、配置 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<link rel="stylesheet/less" type="text/css" href="/color.less" />
<script>
window.less = {
async: false,
env: 'production',
javascriptEnabled: true,
modifyVars: {
'primary-color': 'orange',
}
};
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script>
</body>
</html>
6、效果
启动服务,我们就可以看到:
我们动态修改一下,在控制台将主题色改为粉色的,执行下面代码
window.less.modifyVars({"@primary-color": "pink"})
我们可以看到主题色就改变了。
关于生成的 color.less
文件,可以访问 http://localhost:8080/color.less
查看
更多推荐
所有评论(0)