前端换肤以及更换字体大小

引言

前端换肤,旨在更换web前端应用的主题,来满足用户在不同时期的实际需求。

技术原理

前端换肤的技术原理有很多种这里给大家介绍一种,css 变量 + 主题类型。就是通过不同的类名实现相同的 css 变量,但是其 css 变量的值又是各自实现的,之后在编写组件时全部将写死的值换成对应的 css 变量即可。

实现步骤

假设我们要实现 dark 和 day 两种不同主题。

1、定义 dark 主题 theme/dark/color.less

less 复制代码
@mainColor: #01305f;
@mainTextColor: #ffffff;
@mainBgColor: #012447;

//覆盖 第三方库主题色 例如 ant-design-vue
@primary-color: @mainColor;

以下代码中 关键代码是 在 .dark 类名下 @import 专属于 dark 的 color 以及定义专属于 dark 的 css 变量。注意 css 变量名保持.day 统一

重写第三方库

如果项目中恰好使用了第三方库可以参考第三方库的 less / scss 变量,以及 css 类名重写皮肤。

theme/dark/index.less

less 复制代码
.dark {
  @import "./color.less";
  --main-color: @mainColor;
  --main-text-color: @mainTextColor;
  --main-bg-color: @mainBgColor;
  // 重写第三方库className
  .ant-radio-button-wrapper {
    color: @mainTextColor;
    background-color: @mainBgColor;
  }
}

2、定义 day 主题 theme/day/color.less

less 复制代码
@mainColor: #ffffff;
@mainTextColor: black;
@mainBgColor: #f0f2f5;

//覆盖 第三方库主题色 例如 ant-design-vue
@primary-color: @mainColor;

theme/day/index.less

less 复制代码
.day {
  @import "./color.less";
  --main-color: @mainColor;
  --main-text-color: @mainTextColor;
  --main-bg-color: @mainBgColor;
  // 重写第三方库className
  .ant-radio-button-wrapper {
    color: @mainTextColor;
    background-color: @mainBgColor;
  }
}

内部库

上面的代码使用了 less 如果使用 css 可以参考以下方式

如果内部有多个项目需要换肤 或者多个组件库需要替换变量, 建议将 css 变量和皮肤打包成 npm 包,各个项目和组件库引用同一个 css npm 包即可。

css 复制代码
:root{
--day--main-color: #ffffff;
--day--main-text-color: black;
--day--main-bg-color: #f0f2f5;
--dark--main-color: #01305f;
--dark--main-text-color: #ffffff;
--dark--main-bg-color: #012447;
}
.dark {
  --main-color: var(-dark--main-color);
  --main-text-color: var(--dark--main-text-color);
  --main-bg-color: var(--dark--main-bg-color);
}
.day {
  --main-color: var(-day--main-color);
  --main-text-color: var(--day--main-text-color);
  --main-bg-color: var(--day--main-bg-color);
}

以上只给出了皮肤样式,字体样式结构原理是一样的就不赘述了。

使用

Vue 举例:

项目内所有的皮肤颜色和字体大小均使用 css 变量后 我们只需更换 最大容器元素的 皮肤类名 即可做到换肤。

vue 复制代码
<template>
  <div id="app" :class="[theme, fontSize]">
    <img src="./assets/logo.png" />
    <br />
    <a-radio-group :value="fontSize" @change="handleSizeChange">
      <a-radio-button value="large"> Large </a-radio-button>
      <a-radio-button value="middle"> Default </a-radio-button>
      <a-radio-button value="small"> Small </a-radio-button>
    </a-radio-group>
    <a-radio-group :value="theme" @change="handleThemeChange">
      <a-radio-button value="day"> Day </a-radio-button>
      <a-radio-button value="dark"> Dark </a-radio-button>
    </a-radio-group>
  </div>
</template>

<script>

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return {
      theme: "day",
      fontSize: "middle",
    };
  },
  methods: {
    handleSizeChange(e) {
      this.fontSize = e.target.value;
    },
    handleThemeChange(e) {
      this.theme = e.target.value;
    },
  },
};
</script>

<style lang="less">
#app {
  height: 100%;
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: var(--main-text-color);
  background-color: var(--main-bg-color);
  font-size: var(--main-font-size);
}
</style>

其中

css 复制代码
#app{
  color: var(--main-text-color);
  background-color: var(--main-bg-color);
  font-size: var(--main-font-size);
}

为关键代码

后续所有样式代码用 css 变量替代即可。

其核心原理是:不同皮肤类名下实现了相同名称的 css 变量,它们各自引用了各自的颜色和像素尺寸实现,当 css类名 改变时,类名内部实现的 css 变量 的值也同时改变了

(完)

相关推荐
Lupino23 分钟前
被 React “玩弄”的 24 小时:为了修一个不存在的 Bug,我给大模型送了顿火锅钱
前端·react.js
米丘29 分钟前
了解 Javascript 模块化,更好地掌握 Vite 、Webpack、Rollup 等打包工具
前端
Heo31 分钟前
深入 React19 Diff 算法
前端·javascript·面试
滕青山32 分钟前
个人所得税计算器 在线工具核心JS实现
前端·javascript·vue.js
小怪点点33 分钟前
手写promise
前端·promise
国思RDIF框架41 分钟前
RDIFramework.NET Web 敏捷开发框架 V6.3 发布 (.NET8+、Framework 双引擎)
前端
Mintopia43 分钟前
如何在有限的时间里,活出几倍的人生
前端
炫饭第一名43 分钟前
速通Canvas指北🦮——变形、渐变与阴影篇
前端·javascript·程序员
Neptune144 分钟前
让我带你迅速吃透React组件通信:从入门到精通(上篇)
前端·javascript
阿懂在掘金1 小时前
Vue 表单避坑(一):为什么 v-model 绑定对象属性会偷偷修改父组件数据?
前端·vue.js