Home > Article > Web Front-end > Vue uses CSS variables to implement the theme switching function
Theme management can often be seen on websites. The general idea is to separate the theme-related CSS styles and load the corresponding CSS style files when the user selects the theme. Most browsers are now well compatible with CSS variables, and themed styles are easier to manage. Recently, I used CSS variables to do a theming practice in the Vue project. Let’s take a look at the whole process.
Github project address https://github.com/JofunLiang/vue-project-themable-demo
Demo address https://jofunliang.github .io/vue-project-themable-demo/
Feasibility test
In order to test the feasibility of the method, create a new themes folder under the public folder. And create a new default.css file in the themes folder:
:root { --color: red; }
Recommended learning: CSS video tutorial
in Introduce external style theme.css into the index.html file of the public folder, as follows:
<!DOCTYPE html> <html> <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>vue-skin-peeler-demo</title> <!-- 引入themes文件夹下的default.css --> <link rel="stylesheet" type="text/css" href="src/themes/default.css" rel="external nofollow"> </head> <body> <noscript> <strong>We're sorry but vue-skin-peeler-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
Then, use CSS variables in Home.vue:
<template> <div> <div :class="$style.demo">变红色</div> </div> </template> <script> export default { name: 'home' } </script> <style module> .demo { color: var(--color); } </style>
Then , run the project and open the page in the browser, the page displays normally.
Note: @vue/cli using the link tag to introduce css styles may report an error "We're sorry but vue-skin-peeler-demo doesn't work properly without JavaScript enabled. Please enable it to continue ." This is caused by @vue/cli packaging all files in the src directory through webpack. Therefore, static file resources must be placed in the public (if @vue/cli 2.x version is placed in static) folder.
Implementing theme switching
The idea of theme switching here is to replace the href attribute of the link tag. Therefore, you need to write a replacement function in src Create a new themes.js file in the directory, the code is as follows:
// themes.js const createLink = (() => { let $link = null return () => { if ($link) { return $link } $link = document.createElement('link') $link.rel = 'stylesheet' $link.type = 'text/css' document.querySelector('head').appendChild($link) return $link } })() /** * 主题切换函数 * @param {string} theme - 主题名称, 默认default * @return {string} 主题名称 */ const toggleTheme = (theme = 'default') => { const $link = createLink() $link.href = `./themes/${theme}.css` return theme } export default toggleTheme
Then, create default.css and dark.css under the themes file Two theme files. Create CSS variables to implement theming. To implement theme switching with CSS variables, please refer to another article. First Contact with CSS Variables
Compatibility
IE browser and some older browsers do not support CSS variables, therefore, Requires css-vars-ponyfill, a ponyfill that provides client-side support for CSS custom properties (also known as "CSS variables") in both older and modern browsers. Since you need to enable watch monitoring, you also need to install MutationObserver.js.
Installation:
npm install css-vars-ponyfill mutationobserver-shim --save
Then, introduce and use it in the themes.js file:
// themes.js import 'mutationobserver-shim' import cssVars from 'css-vars-ponyfill' cssVars({ watch: true }) const createLink = (() => { let $link = null return () => { if ($link) { return $link } $link = document.createElement('link') $link.rel = 'stylesheet' $link.type = 'text/css' document.querySelector('head').appendChild($link) return $link } })() /** * 主题切换函数 * @param {string} theme - 主题名称, 默认default * @return {string} 主题名称 */ const toggleTheme = (theme = 'default') => { const $link = createLink() $link.href = `./themes/${theme}.css` return theme } export default toggleTheme
After turning on watch, click on IE 11 browser Toggling the theme switch doesn't work. Therefore, if you re-execute cssVars() every time you switch the theme, you still cannot switch the theme. The reason is that re-executing cssVars() after turning on watch is invalid. Finally, the only option is to turn off the watch and then turn it back on. The themes.js code for successfully switching the theme is as follows:
// themes.js import 'mutationobserver-shim' import cssVars from 'css-vars-ponyfill' const createLink = (() => { let $link = null return () => { if ($link) { return $link } $link = document.createElement('link') $link.rel = 'stylesheet' $link.type = 'text/css' document.querySelector('head').appendChild($link) return $link } })() /** * 主题切换函数 * @param {string} theme - 主题名称, 默认default * @return {string} 主题名称 */ const toggleTheme = (theme = 'default') => { const $link = createLink() $link.href = `./themes/${theme}.css` cssVars({ watch: false }) setTimeout(function () { cssVars({ watch: true }) }, 0) return theme } export default toggleTheme
To view all codes, please go to the Github project address.
Remember the theme
To implement the function of remembering the theme, one is to save the theme to the server, and the other is to use the local storage theme. For convenience, the local storage method of theme is mainly used here, that is, localStorage is used to store the theme. For specific implementation, please visit the Github project address.
This article comes from the PHP Chinese website, CSS tutorial column, welcome to learn
The above is the detailed content of Vue uses CSS variables to implement the theme switching function. For more information, please follow other related articles on the PHP Chinese website!