1. Technical Core
Switch the theme style by switching css
the selector.
Keep the same style in the component, and extract the style that needs to be changed
Provide a variety of styles, define a corresponding CSS selector for different themes
Set different styles according to different themes by switching CSS selectors
2. Implementation method
Extract common CSS styles and switch themes through variables
1. Create a js file that stores public css variables, store the css variables that need to be defined in the js file, and change the skin through the css-vars-ponyfill plug-in
// variable.js
// 字体变量
const baseSize = {
"--font-size-first-level-title": "18px",
"--font-size-second-level-title": "16px",
};
// 浅色
export const lightTheme = {
"--themeColor": "#01cc8c",
"--left-bg": "rgb(182, 23, 23)",
"--right-bg": "rgb(63, 9, 9)",
"--top-bg": "rgb(6, 36, 65)",
"--bottom-bg": "rgb(55, 214, 10)",
...baseSize,
};
// 深色
export const darkTheme = {
"--themeColor": "#56518C",
"--left-bg": "#0094ff",
"--right-bg": "blue",
"--top-bg": "red",
"--bottom-bg": "pink",
...baseSize,
};
2. Use css variables in the page
<style lang="sass">
.left {
background-color: var(--left-bg);
color: var(--themeColor);
height: 500px;
flex: 1;
}
</style>
3. Install the css-vars-ponyfill plugin
npm i css-vars-ponyfill
4. Encapsulate js for switching themes
// theme.js
import { lightTheme, darkTheme } from "../src/assets/js/variable";
import cssVars from "css-vars-ponyfill";
export const initTheme = (theme = true) => {
document.documentElement.setAttribute("data-theme", theme ? "light" : "dark");
cssVars({
watch: true, // 当添加,删除或修改其<link>或<style>元素的禁用或href属性时,ponyfill将自行调用
variables: theme ? lightTheme : darkTheme, // variables 自定义属性名/值对的集合
onlyLegacy: false, // false 默认将css变量编译为浏览器识别的css样式 true 当浏览器不支持css变量的时候将css变量编译为识别的css
});
};
5. Call theme.js in main.js
import { initTheme } from './theme'
let theme = 条件 ? false : true
initTheme(theme)
6. How to solve the picture path?
// main.js
// lightTheme 和 darkTheme 是文件夹名字
Vue.prototype.SKIN_IMAGE_PATH = 条件 ? 'lightTheme' : 'darkTheme'
// .vue文件
export default {
data () {
return {
tip: require(`@assets/img/theme/${this.SKIN_IMAGE_PATH}/tip.png`),
}
}
}