在vue中实现antd的动态主题的代码示例
作者:淡淡的夏季
在需求开发阶段,鉴于项目采用了antd作为基础组件库,确保组件外观与antd一致变得尤为重要,这包括颜色、字体大小及尺寸等样式的统一,然而,截至当前antd-vue尚未实现这一便捷的CSS变量特性,但理解其背后的实现机制后,我们可以自行构建这一功能,需要的朋友可以参考下
在需求开发阶段,鉴于项目采用了antd作为基础组件库,确保组件外观与antd一致变得尤为重要,这包括颜色、字体大小及尺寸等样式的统一。antd在其最新版本中,通过CSS变量(也称为CSS自定义属性)的形式,将所有样式整合至<style>标签内,极大地方便了开发者通过var(--antd-xxx)语法直接引用antd的样式设置。
然而,截至当前(版本4.2.3),antd-vue尚未实现这一便捷的CSS变量特性。但理解其背后的实现机制后,我们可以自行构建这一功能。
实现思路简述:
- 获取Antd样式:利用
theme.userToken接口(或类似机制,具体依据antd-vue或自定义主题的接口而定),提取antd的样式定义。 - 注入样式:将获取到的样式通过JavaScript动态地添加到HTML文档的
<style>标签中,确保组件能够访问到这些CSS变量。 - 动态更新:为了支持样式变量的动态变更(如主题切换),需监听
theme.userToken或相关主题配置的变化,并实时更新DOM中的<style>标签内容,同时确保样式更新的单一性和高效性,避免冗余或冲突。
通过以上步骤,即使antd-vue当前版本未内置CSS变量支持,我们也能通过自定义实现来达成与antd样式的高度一致,提升开发效率和组件的可用性。
具体实现,下面代码复制到到本地,并允许即可
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://registry.npmmirror.com/@babel/standalone/^7/files/babel.min.js"></script>
<script src="https://registry.npmmirror.com/vue/3/files/dist/vue.global.js"></script>
<script src="https://registry.npmmirror.com/dayjs/^1/files/dayjs.min.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/customParseFormat.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/advancedFormat.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/weekday.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/localeData.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/weekOfYear.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/weekYear.js"></script>
<script src="https://registry.npmmirror.com/dayjs/1.11.11/files/plugin/quarterOfYear.js"></script>
<script src="https://registry.npmmirror.com/ant-design-vue/4.2.3/files/dist/antd.min.js"></script>
<style>
.test {
color: var(--antv-color-primary)
}
</style>
</head>
<body>
<div id="root"></div>
<script>
Babel.registerPreset("env-plus", {
presets: [
[Babel.availablePresets["env"]],
[Babel.availablePresets['react'], { pragma: 'h', pragmaFrag: "Fragment", }]
],
plugins: [],
});
const toLine = (name) => {
if (!name) return name
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
}
</script>
<!-- 代码开始 -->
<script type="text/babel" data-presets="env-plus">
const { createApp, ref, h, watch } = Vue
const { Button, ConfigProvider, theme, Table } = antd
const { useToken } = theme
const styleDom = document.createElement('style')
document.head.appendChild(styleDom)
const setCssVar = (data) => {
const list = Object.entries((data)).map(([key, val]) => {
return `--antv-${toLine(key)}: ${val}`
}).join(';')
const css = `:root { ${list} }`
styleDom.textContent = css
}
const App = {
setup() {
const { token } = useToken()
watch(token, (newToken) => {
setCssVar(newToken)
}, {
immediate: true
})
const myTheme = ref({
colorPrimary: 'red',
colorTextHeading: 'red',
colorText: 'red',
fontWeightStrong: 400
})
const handleTheme = () => {
myTheme.value.colorPrimary = myTheme.value.colorPrimary === 'red' ? 'green' : 'red'
}
const dataSource = [
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
];
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
]
return () => {
return <ConfigProvider
theme={{ token: myTheme.value }}
>
<Button type="primary" onClick={handleTheme}>切换主题</Button>
<div class='test'>使用--antv-colorPrimary变量</div>
<Table columns={columns} dataSource={dataSource} />
</ConfigProvider>
}
},
}
const app = createApp(App)
app.mount('#root')
</script>
</body>
</html>
到此这篇关于在vue中实现antd的动态主题的代码示例的文章就介绍到这了,更多相关vue antd动态主题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
