【vue-win10-admin交個朋友系列】之主題切換方案

前言

【vue-koa2全棧擼win10風格管理系統】交個朋友系列文章,帶各位全棧擼win10風格管理系統開發,固然項目也參考不少優秀的先後端項目構建方案和我在工做中的一些中的一些經驗應用,主要是交個朋友的心態,若是你對這個項目有興趣,也但願你的加入一塊兒完善維護這個項目,let go~~~css

完整項目地址:vue-win10-adminhtml

本篇文章是【Vue+Koa2+Mysql全棧擼win10風格管理系統】交個朋友系列之主題切換方案

先來一個主題切換效果圖,主要實現背景圖片的切換和主題色的切換,並且刷新瀏覽器仍是能保持vue

1、實現功能主要技術點

一、利用localStorage瀏覽器本地存儲主題設置信息(固然也能夠存儲在數據庫裏)
二、scss抽離主題文件中涉及到顏色的 CSS 值替換成關鍵詞
三、實時監聽localStorage的變化,關鍵詞再換回生成的相應的顏色值或者背景圖片git

2、抽取主題變量,封裝mixin

在目錄 styles/theme-variable.scss先把主題文件中涉及到顏色的 CSS 值替換成關鍵詞,作了個別地方進行皮膚切換github

$background-color-theme1: #409EFF;
$background-color-theme2: #0078D7;
$background-color-theme3: #C30052;
$background-color-theme4: #9A0089;
$background-color-theme5: #67C23A;
$background-color-theme6: #CA5010;
$background-color-theme7: #CA5010;
$background-color-theme8: red;
$background-color-theme9: #303133;
$background-color-theme10: #606266;
$background-color-theme11: #909399;
$background-color-theme12: #C0C4CC;
$background-color-theme13: #DCDFE6;
$background-color-theme14: #E4E7ED;
$background-color-theme15: #EBEEF5;
$background-color-theme16: #FFFFFF;

$font-color-black: #303133;
$font-color-white: #FFFFFF;

$startMenu-background-color-black: rgba(19, 23, 28, 0.9);
$startMenu-background-color-white: #F2F6FC;

在目錄 styles/theme-mixin.scss 設置背景顏色封裝成一個mixin方法(包括字體大小,字體顏色,進行封裝),@mixin經過自定義屬性[data-theme=""]去識別對應的顏色變量sql

@mixin background-color($color) {
 background-color: $color;
 [data-theme="theme1"] & {
   background-color:$background-color-theme1;
 }
 [data-theme="theme2"] & {
   background-color:$background-color-theme2;
 }
 [data-theme="theme3"] & {
   background-color:$background-color-theme3;
 }
 [data-theme="theme4"] & {
   background-color:$background-color-theme4;
 }
 [data-theme="theme5"] & {
   background-color:$background-color-theme5;
 }
 [data-theme="theme6"] & {
   background-color:$background-color-theme6;
 }
 [data-theme="theme7"] & {
   background-color:$background-color-theme7;
 }
 [data-theme="theme8"] & {
   background-color:$background-color-theme8;
 }
 [data-theme="theme9"] & {
   background-color:$background-color-theme9;
 }
 [data-theme="theme10"] & {
   background-color:$background-color-theme10;
 }
 [data-theme="theme11"] & {
   background-color:$background-color-theme11;
 }
 [data-theme="theme12"] & {
   background-color:$background-color-theme12;
 }
 [data-theme="theme13"] & {
   background-color:$background-color-theme13;
 }
 [data-theme="theme14"] & {
   background-color:$background-color-theme14;
 }
 [data-theme="theme15"] & {
   background-color:$background-color-theme15;
 }
 [data-theme="theme16"] & {
   background-color:$background-color-theme16;
 }
}

在頁面上須要用到切換膚色的地方引用樣數據庫

@import "~@/styles/theme-mixin.scss";
 @import "@/styles/theme-variable.scss";
 @include background-color($background-color-theme1); //引用背景顏色設置
 @include font-color($font-color-white); //引用字體設置

例如在layout頁面佈局裏相關文件裏(部分展現),這裏是基礎scss技能再也不作過多的講解後端

<style lang="scss" scoped>
@import "~@/styles/theme-mixin.scss";
@import "@/styles/theme-variable.scss";
.window-wrapper {
position: absolute;
min-width: 1280px;
min-height: 80%;
z-index: 9;
.window-header {
  height: 40px;
  line-height: 40px;
  @include background-color($background-color-theme1);
  transition: all .5s;
  display: flex;

  .window-title {
    flex: 1;
    padding-left: 10px;
    user-select: none;
    color: #fff;
    @include font-color($font-color-white);
    transition: all .5s;

3、主題顏色設置

在目錄 src/views/config/coloer/index.vue 中更換主題時的操做代碼api

<template>
  <div class="colour-wrapper">
    <preview></preview>
    <div class="set-wrapper">
      <div class="title">主題色</div>
      <div class="colour-list">
        <div v-for="index of 16" :key="index" :class="'theme-color-'+index" @click="changeTheme(index)"></div>
      </div>
    </div>
  </div>
</template>

<script>
import preview from '@/components/preview.vue'
import { localKey } from '@/settings'
export default {
  components: {
    preview
  },
 data() {
    return {
    }
  },
 methods:{
   changeTheme(index) {
     let theme = "theme" + index
    window.document.documentElement.setAttribute('data-theme', theme)
   } 
 }
}
</script>

經過再選擇主題的時候,我在這裏主題色16個能夠選擇,列表是用v-for
列表渲染出來的,每一個顏色綁定一個一個點擊事件,經過DOM操做在設置自定義屬性[data-theme],會在html裏添加自定義屬性data-theme,這樣就是實現了皮膚切換
瀏覽器

可是這樣有什麼缺點呢?

當你刷新瀏覽器的時候,你會發現這個設置就不生效了,
因此接下來考慮存儲到瀏覽器緩存裏去

4、localStorage本地存儲主題設置

總所周知,vue沒法監聽localstorage的變化的,這裏經過註冊全局方法,而後經過事件派發的方式實現localstorage的響應式
根據咱們項目中的主題相關的屬性,目前有主題和背景圖相關的設置存儲在一個對象裏
咱們在 src/utils/storage.js裏針對原生localStorage 的api都封裝一層,生成本身的公用主題設置模塊存儲派發模塊

export const dispatchSetLocalStore = (key, type, value) => {
  let settings = _getLocalStore(key,'JSONStr') || {
    theme: 11,
    taskbarMode: 'bottom',
    bgSrc: ''
  }
  switch(type) {
    case 'bgSrc':
      settings.bgSrc = value
      break
    case 'theme':
      settings.theme = value
      break
    case 'taskbarMode':
      settings.taskbarMode = value
      break
  }
  settings = JSON.stringify(settings)
    // 建立一個StorageEvent事件
  let newStorageEvent = document.createEvent('StorageEvent');
  const storage = {
      setItem: function (k, val) {
        localStorage.setItem(k, val)
        // 初始化建立的事件
        newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null)
        // 派發對象
        window.dispatchEvent(newStorageEvent)
      }
  }
  return storage.setItem(key, settings)
}

而後在src/main.js對vue添加一個原型屬性

import { dispatchSetLocalStore } from './utils/storage'
Vue.prototype.setLocalStore = dispatchSetLocalStore

此時此刻咱們就能夠在vue文件裏監聽到變化了

<template>
  <div id="app"  :style="{ background: 'url('+bgSrc+')'}" :data-theme="theme">
    <router-view />
  </div>
</template>

<script>
import { _getLocalStore } from '@/utils/storage'
import { localKey } from '@/settings'
export default {
  name: 'App',
  data() {
   return {
     bgSrc: _getLocalStore(localKey, 'JSONStr') && _getLocalStore(localKey, 'JSONStr').bgSrc  ? _getLocalStore(localKey, 'JSONStr').bgSrc : require('@/assets/bg_01.jpg'),
     theme: _getLocalStore(localKey, 'JSONStr') && _getLocalStore(localKey, 'JSONStr').theme  ? _getLocalStore(localKey, 'JSONStr').theme : 'theme1'
    }
  },
  created(){
    window.addEventListener('setItem', () => {
      let local = _getLocalStore(localKey, 'JSONStr')
      this.bgSrc = local && local.bgSrc ? local.bgSrc : this.bgSrc
      this.theme = local && local.theme ? local.theme : this.theme
    })
  },
}
</script>

在目錄 src/views/config/coloer/index.vue 中更換主題時的操做代碼
此時就不是 window.document.documentElement.setAttribute('data-theme', theme)
而是this.setLocalStore(localKey, 'theme', theme)

5、總結

換膚的方式主要是對涉及到顏色的 CSS 值替換成關鍵詞,根據用戶選擇的主題色生成一系列對應的顏色值,用戶選的主題設和背景圖片通通經過鍵值對存儲在localstorage,而後經過全局事件派發,響應式獲取localstorage,經過自定義屬性的屬性值,對應把關鍵詞再換回剛剛生成的相應的顏色值,切換背景圖片,而後分別對其加一些切換動畫,顯得換膚和切換背景圖片天然~
【Vue+Koa2+Mysql全棧擼win10風格管理系統】交個朋友系列文章,會根據項目搭建和講功能點實現,歡迎你們一塊兒交流~
完整項目地址:vue-win10-admin

相關文章
相關標籤/搜索