Black and white theme skinning solution

foreword

insert image description here
insert image description here
When switching, do not re-adjust the interface

Implementation

1. First create a js file that stores public css variables

Store the css variables that need to be defined in the js file, for example (variable.js)
insert image description here

2. Use these css variables on the page

insert image description here

3. Install css-vars-ponyfillthe plugin

npm i css-vars-ponyfill

" css-vars-ponyfill" Official concept: a ponyfill that provides client-side support for CSS custom properties (aka "CSS variables") in legacy and modern browsers. (For specific usage and concepts, please refer to the official website)

4. Encapsulate the js that switches the theme, and make an initialization call in main.js

theme.js

// theme.js
import {
    
     lightTheme, darkTheme } from "@/assets/js/variable"
import cssVars from "css-vars-ponyfill"
export const initTheme = (theme) => {
    
    
  document.documentElement.setAttribute("data-theme", theme ? "dark" : "light")
  cssVars({
    
    
    watch: true, // 当添加,删除或修改其<link>或<style>元素的禁用或href属性时,ponyfill将自行调用
    variables: theme ? darkTheme : lightTheme, // variables 自定义属性名/值对的集合
    onlyLegacy: false, // false  默认将css变量编译为浏览器识别的css样式  true 当浏览器不支持css变量的时候将css变量编译为识别的css
  })
}

5. main.js call

import {
    
     initTheme } from './theme'
let theme = localStorage.getItem('theme') === 'light' ? false : true
initTheme(theme)

6. Home.vue switch theme (I have pictures in the folder here)

<template>
  <div class="home">
    <div>
      <el-switch
        v-model="theme"
        @change="changeSkin"
        active-text="黑色背景"
        inactive-text="白色背景"
      >
      </el-switch>
    </div>
    <div class="box">
      <div class="left"></div>
      <div class="right"></div>
    </div>
    <div class="less_box add">
      <img :src="avatar" alt="" />
      <el-input v-model="input" placeholder="请输入内容"></el-input>
    </div>
  </div>
</template>

<script>
import {
    
     initTheme } from '@/theme'
import {
    
     mapState, mapMutations } from 'vuex'
// import BUS from '@/utils/bus'
export default {
    
    
  data () {
    
    
    return {
    
    
      theme: true,
      input: ''
    }
  },
  computed: {
    
    
    ...mapState({
    
     sysTheme: 'theme' }),
    avatar () {
    
    
      // let theme = this.sysTheme === false ? 'light' : 'dark'
      return require(`@/assets/images/logo-${
      
      this.sysTheme}.png`)
    }
  },
  watch: {
    
    
  },
  mounted () {
    
    
    console.log(this.sysTheme);
    this.theme = this.sysTheme === 'dark' ? true : false
    // document.body.style.setProperty('--bottom-bg', '#0094ff');
    // initTheme(this.theme)
    // console.log(1111);
  },
  methods: {
    
    
    ...mapMutations({
    
    
      setTheme: 'setTheme'
    }),
    changeSkin () {
    
    
      localStorage.setItem('theme', this.theme ? 'dark' : 'light')
      this.setTheme(this.theme ? 'dark' : 'light')
      initTheme(this.theme)
    },
    // setThemeValue (theme) {
    
    
    //   theme = theme ? "light" : "dark";
    //   this.avatar = require(`@/assets/images/logo-${theme}.png`);
    // }
  }
}
</script>
<style lang="less" scoped>
.home {
    
    
  .box {
    
    
    margin-top: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
    .left {
    
    
      background-color: var(--left-bg);
      height: 500px;
      flex: 1;
    }
    .right {
    
    
      background-color: var(--right-bg);
      height: 500px;
      flex: 1;
    }
  }
  .less_box {
    
    
    height: 200px;
    width: 1500px;
    display: flex;
  }
}
</style>

7. Use in app.vue

insert image description here

8. vuex persistence

import Vue from "vue";
import Vuex from "vuex";
// import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex);

export default new Vuex.Store({
    
    
  state: {
    
    
    theme: localStorage.getItem('theme') === 'light' ? 'light' : 'dark'
  },
  mutations: {
    
    
    setTheme (state, data) {
    
    
      state.theme = data
    }
  },
  actions: {
    
    },
  modules: {
    
    },
  // plugins: [
  //   createPersistedState({
    
    
  //     storage: window.localStorage,
  //     reducer (val) {
    
    
  //       // console.log(val);
  //       return val
  //     }
  //   })]
});

So far, all the color switching and picture switching have been completed. Let me talk about the idea of ​​picture switching: the path of the picture is mainly obtained by using computed, so when we change the theme, the theme value saved by vuex will change, and the computed This change will be monitored to achieve the effect of replacing the image path.

Guess you like

Origin blog.csdn.net/weixin_44582045/article/details/132474487