从零搭建自己的Vue管理端框架(六)

1,196 阅读7分钟
Hello大家好,本章我们添加修改系统主题样式功能 。有问题可以联系我mr_beany@163.com。另求各路大神指点,感谢

现在很多修改主题功能都利用less来做,那么除了less,jquery等我们还有没有其他方法来修改主题样式了呢?本章我们利用css3中动态样式来修改。

一:css3变量介绍

CSS 中的 “var()” 和 “:root”

var()

var() 函数可以代替元素中任何属性中的值的任何部分。var() 函数不能作为属性名、选择器或者其他除了属性值之外的值。(这样做通常会产生无效的语法或者一个没有关联到变量的值。)

:root

:root 是一个伪类,表示文档根元素,非 IE 及 ie8 及以上浏览器都支持,在: root 中声明相当于全局属性,只要当前页面引用了: root segment 所在文件,都可以使用 var() 来引用

测试:

修改static→css→common.css  添加如下

:root {
  /*头部背景颜色  父级菜单颜色*/
  --headerColor: #202d3d;
  /*子集菜单颜色*/
  --sonMenuColor: #2C3E50;
  /*子集菜单选中颜色*/
  --openSonMenuColor: #21598f;
  /*子菜单选中字体颜色*/
  --openSonFontColor: #fff;
  /*字体颜色*/
  --fontColor: #fff;
  /*整体背景颜色  or  图片*/
  --backgroundStyle: #2C3E50;
  /*view背景颜色*/
  --viewBackgroundStyle: rgba(255, 255, 255, 1);
  /*选中子菜单自字体颜色*/
  --openSonFontColor: #fff;
  /*菜单悬浮时*/
  --userBackgroundStyle: #2C3E50;
  --userFontColor: #fff;
}

修改Home.vue中style如下

<style>
  a {
    color: var(--fontColor);
  }

  .header-div {
    background-color: var(--headerColor);
    color: var(--fontColor);
    height: 70px;
    align-items: center;
    box-shadow: 3px 0 3px rgba(0, 0, 0, .3);
    padding-left: 10px;
    margin-bottom: 20px;
  }

  .header-div-left {
    align-items: center;
  }

  .header-div-left:hover {
    cursor: pointer;
  }

  .header-div-right {
    align-items: center;
    width: calc(100% - 120px);
    justify-content: flex-end;
  }

  .header-div-right :hover {
    cursor: pointer;
  }

  .menu-list-div {
    width: 12%;
    max-width: 190px;
    height: calc(100% - 30px);
    background-color: var(--sonMenuColor);
    font-size: 16px;
    border-radius: 5px;
    padding: 5px;
    overflow-y: auto;
  }

  .menu-list-bgc {
    background-color: var(--sonMenuColor);
    color: var(--fontColor);
    align-items: center;
    padding: 15px;
    cursor: pointer;
  }

  .menuSon-list-bgc {
    margin-top: 5px;
    background-color: var(--headerColor);
    padding: 10px 15px 10px 30px;
    border-radius: 5px;
  }

  .menuSon-list-color {
    background-color: var(--openSonMenuColor);
    color: var(--openSonFontColor);
    border-left: 4px solid;
    cursor: pointer;
  }

  .menuSon-list-color1 {
    color: var(--fontColor);
    padding: 10px 15px 10px 34px;
    cursor: pointer;
  }

  .setting-div {
    position: fixed;
    color: var(--fontColor);
    right: 20px;
    top: 50px;
    width: 125px;
    height: 80px;
    background-color: var(--sonMenuColor);
    z-index: 4;
    font-size: 14px;
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
  }

  .setting-div :hover {
    cursor: pointer;
  }

  .settingOption-div {
    padding: 10px 2px;
    align-items: center;
    justify-content: center;
  }

  .settingOption-div-img {
    width: 15px;
  }

  .settingOption-div-title {
    margin-left: 10px;
  }

  .routerView {
    width: 100%;
    background: var(--viewBackgroundStyle);
    border-radius: 5px;
    height: calc(100% - 20px);
    border: 0;
  }
</style>

效果如下,之前设置的样式依旧有效,那么我们就可以根据这个特点来进行修改样式


二:创建主题配置文件

创建src→const→theme.js

export const THEME = {
  STYLE: [{
    // 主题名字
    'themeName':'默认主题',
    /*头部背景颜色  父级菜单颜色*/
    '--headerColor':'#2C3E50',
    /*子集菜单颜色*/
    '--sonMenuColor':'#2C3E50',
    /*子集菜单选中颜色*/
    '--openSonMenuColor':'#21598f',
    /*字体颜色*/
    '--fontColor':'#fff',
    /*整体背景颜色  or  图片*/
    '--backgroundStyle':'#283542',
    /*view背景颜色*/
    '--viewBackgroundStyle':'rgba(255, 255, 255, 1)',
    // 选中子菜单自字体颜色
    '--openSonFontColor':'#fff',
    // 菜单悬浮时
    '--userBackgroundStyle':'#2C3E50',
    '--userFontColor':'#fff'
  },{
    'themeName':'炫酷主题',
    '--backgroundStyle':'url("https://i4.piimg.com/510372/2bdbeadd3d33f01f.png")',
    '--headerColor':'rgba(255, 255, 255, 0)',
    '--sonMenuColor':'rgba(255, 255, 255, 0)',
    '--openSonMenuColor':'rgba(255, 255, 255, 0)',
    '--fontColor':'#fff',
    '--viewBackgroundStyle':'rgba(255, 255, 255, 0.8)',
    '--openSonFontColor':'#fff',
    // 菜单悬浮时
    '--userBackgroundStyle':'rgba(0,0,0,.5)',
    '--userFontColor':'#fff'
  },{
    'themeName':'书香年华',
    '--backgroundStyle':'url("http://pic.netbian.com/uploads/allimg/170630/160943-14988101838dc4.jpg")',
    '--headerColor':'rgba(255, 255, 255, 0)',
    '--sonMenuColor':'rgba(255, 255, 255, 0)',
    '--openSonMenuColor':'rgba(255, 255, 255, 0)',
    '--fontColor':'#fff',
    '--viewBackgroundStyle':'rgba(255, 255, 255, 0.8)',
    '--openSonFontColor':'#fff',
    // 菜单悬浮时
    '--userBackgroundStyle':'rgba(0,0,0,.5)',
    '--userFontColor':'#fff'
  },{
    'themeName':'渐变主题',
    '--backgroundStyle':'linear-gradient(120deg,#bc00e3,#4efffb)',
    '--headerColor':'rgba(255, 255, 255, 0)',
    '--sonMenuColor':'rgba(255, 255, 255, 0)',
    '--openSonMenuColor':'rgba(255, 255, 255, 0)',
    '--fontColor':'#fff',
    '--viewBackgroundStyle':'rgba(255, 255, 255, 0.8)',
    '--openSonFontColor':'#fff',
    // 菜单悬浮时
    '--userBackgroundStyle':'rgba(188, 0, 227, 0.4)',
    '--userFontColor':'#fff'
  },{
    'themeName':'黑色主题',
    '--backgroundStyle':'#002253',
    '--headerColor':'rgba(255, 255, 255, 0)',
    '--sonMenuColor':'rgba(255, 255, 255, 0)',
    '--openSonMenuColor':'hsla(0,0%,100%,.05)',
    '--fontColor':'#ff929a',
    '--viewBackgroundStyle':'#fff',
    '--openSonFontColor':'#ffb870',
    // 菜单悬浮时
    '--userBackgroundStyle':'rgba(255, 255, 255, 0)',
    '--userFontColor':'#ff929a'
  },{
    'themeName':'白色主题',
    '--backgroundStyle':'#eceef3',
    '--headerColor':'#fff',
    '--sonMenuColor':'#fff',
    '--openSonMenuColor':'#e2edff',
    '--fontColor':'rgb(102, 102, 102)',
    '--viewBackgroundStyle':'#fff',
    '--openSonFontColor':'#00AFF9',
    // 菜单悬浮时
    '--userBackgroundStyle':'#e2edff',
    '--userFontColor':'#00AFF9'
  }],
};

//修改样式
export const setThemeStyle = function(index) {
  var themeStyleObj = THEME.STYLE[index];
  for (var Key in themeStyleObj){
    if(Key!= 'themeName'){
      //根据变量名  修改变量的值,以达到更换主题的目的
      document.documentElement.style.setProperty(Key, themeStyleObj[Key]);
    }
  }
} 

大家也可以根据自己需求来配置不同主题。

三:添加工具类

创建src→utils→storage.js

//LocalStorage存储

export const setJsonLocalStorageItem = function(key, value) {
	localStorage.removeItem(key);
	var json = JSON.stringify(value);
	localStorage.setItem(key, json);
}

export const getJsonLocalStorageItem = function(key) {
	return JSON.parse(localStorage.getItem(key));
}

export const setStrLocalStorageItem = function(key, value) {
	localStorage.removeItem(key)
	localStorage.setItem(key, value)
}

export const getStrLocalStorageItem = function(key) {
	return localStorage.getItem(key)
}

export const removeLocalStorageItem = function(key) {
	localStorage.removeItem(key);
}
export const cleanLocalStorage = function() {
	localStorage.clear();
}


//SessionStorage  存储
export const setJsonSessionStorageItem = function(key, value) {
	sessionStorage.removeItem(key);
	var json = JSON.stringify(value);
	sessionStorage.setItem(key, json);
}

export const getJsonSessionStorageItem = function(key) {
	return JSON.parse(sessionStorage.getItem(key));
}

export const setStrSessionStorageItem = function(key, value) {
	sessionStorage.removeItem(key)
	sessionStorage.setItem(key, value)
}

export const getStrSessionStorageItem = function(key) {
	return sessionStorage.getItem(key)
}

export const removeSessionStorageItem = function(key) {
	sessionStorage.removeItem(key);
}
export const cleanSessionStorage = function() {
	sessionStorage.clear();
} 

四:修改Home.vue

<template>
  <div style="height: 100%;background: var(--backgroundStyle);background-size: 100%">
    <div class="header-div disFlex">
      <el-tooltip class="item" effect="light" content="返回首页" placement="right">
        <div class="header-div-left disFlex" @click="gohome()">
          <span style="margin-left: 10px;font-weight: bold;font-size: 20px">MyVue</span>
        </div>
      </el-tooltip>
      <div class="disFlex header-div-right">
        <div @click="isUpdateTheme = true" style="font-size: 20px">
          <i class="el-icon-menu"></i>
        </div>
        <div @click="showLoginOut = !showLoginOut" style="padding: 0px 10px;">
          <img src="../images/userHeaderImg.png" style="width: 25px;"/>
        </div>
        <div @click="showLoginOut = !showLoginOut">
          <span>{{userName}}</span>
        </div>
      </div>
    </div>
    <div class="disFlex" style="height: calc(100% - 90px);padding:0 15px;">
      <div class="menu-list-div">
        <div v-for="(menu,index) in menuList" :key="menu.id">
          <div @click="showMenu(index)" class="menu-list-bgc disFlex">
            <div style="width: 80%;">
              <span>{{menu.menuName}}</span>
            </div>
            <div style="width: 20%;text-align: right;">
              <i class="el-icon-arrow-right"
                 :class="[menu.isOpen == 1?'rotate':'rotate1']"
                 v-if="menu.adminMenuList.length > 0"></i>
            </div>
          </div>
          <el-collapse-transition>
            <div v-show="menu.isOpen==1">
              <a>
                <router-link tag="li" :to="menuSon.query == undefined? menuSon.path : menuSon.path + menuSon.query"
                             v-for="(menuSon,index1) in menu.adminMenuList"
                             :key="menuSon.id">
                  <div class="menuSon-list-bgc"
                       @click="showMenuSon(index,index1)"
                       :class="[menuSon.isOpen==1?'menuSon-list-color':'menuSon-list-color1']">
                    <span>{{menuSon.menuName}}</span>
                  </div>
                </router-link>
              </a>
            </div>
          </el-collapse-transition>
        </div>
      </div>
      <div style="width: 100%;margin-left: 20px;">
        <router-view class="routerView" :key="$route.fullPath"></router-view>
      </div>
    </div>

    <!--更换主题-->
    <el-dialog title="更换主题" :visible.sync="isUpdateTheme">
      <el-radio-group v-model="themeIndex" @change = "updateTheme">
        <el-radio :label="index" v-for="(theme,index) in themeList" :key = "index">{{theme.themeName}}</el-radio>
      </el-radio-group>
    </el-dialog>
  </div>
</template>
<script>
  import * as theme from '../const/theme';
  //引入storage
  import * as storage from "./../utils/storage";
  export default {
    data() {
      return {
        menuList: [],
        userName: '',
        themeIndex: 0,//默认主题
        isUpdateTheme:false,
        themeList:[],
      }
    },
    created: function () {
      this.getMenuList();
      this.userName = "MyVue";
      this.themeList = theme.THEME.STYLE;
      this.setTheme();  //页面加载时加载主题
    },
    methods: {
      getMenuList(){
        this.menuList = [
          {
            menuName: "外部链接", isOpen: 0,
            adminMenuList: [
              {menuName: "百度", isOpen: 0, path: "/Iframe", query:"/https%3A%2F%2Fwww.baidu.com"},
              {menuName: "Element UI", isOpen: 0, path: "/Iframe", query:"/http%3A%2F%2Felement-cn.eleme.io/#/zh-CN"}
            ]
          },
          {
            menuName: "用户管理", isOpen: 0,
            adminMenuList: [
              {menuName: "查看用户", isOpen: 0, path: "/user"}
            ]
          }
        ];
      },
      setTheme() {
        let storageThemeIndex = storage.getStrLocalStorageItem("storageThemeIndex");
        if (!storageThemeIndex) {
          storage.setStrLocalStorageItem("storageThemeIndex", 0);
        }
        storageThemeIndex = storage.getStrLocalStorageItem("storageThemeIndex");
        this.themeIndex = parseInt(storageThemeIndex);
        this.updateTheme(storageThemeIndex);
      },
      updateTheme(index){
        theme.setThemeStyle(index);
        storage.setStrLocalStorageItem("storageThemeIndex", index);
      },
      showMenu(index) {
        this.menuList.forEach(function (item, i) {
          if (i === index) {
            return;
          }
          item.isOpen = 0;
        })
        this.menuList[index].isOpen = this.menuList[index].isOpen === 1 ? 0 : 1;
        var menu = this.menuList[index];
        menu.adminMenuList.forEach(function (item, i) {
          menu.adminMenuList[i].isOpen = 0;
        })
      },
      showMenuSon(index, index1) {
        var menu = this.menuList[index];
        menu.adminMenuList.forEach(function (item, i) {
          if (i != index1) {
            menu.adminMenuList[i].isOpen = 0;
          } else {
            menu.adminMenuList[i].isOpen = 1;
          }
        })
      },
      closeMenu() {
        this.menuList.forEach(function (item) {
          this.isOpen = 0;
        })
      },
      gohome() {
        this.$router.push({
          path: "/home"
        });
        this.closeMenu();
      },
    }
  }
</script>
<style>
  a {
    color: var(--fontColor);
  }

  .header-div {
    background-color: var(--headerColor);
    color: var(--fontColor);
    height: 70px;
    align-items: center;
    box-shadow: 3px 0 3px rgba(0, 0, 0, .3);
    padding-left: 10px;
    margin-bottom: 20px;
  }

  .header-div-left {
    align-items: center;
  }

  .header-div-left:hover {
    cursor: pointer;
  }

  .header-div-right {
    align-items: center;
    width: calc(100% - 120px);
    justify-content: flex-end;
  }

  .header-div-right :hover {
    cursor: pointer;
  }

  .menu-list-div {
    width: 12%;
    max-width: 190px;
    height: calc(100% - 30px);
    background-color: var(--sonMenuColor);
    font-size: 16px;
    border-radius: 5px;
    padding: 5px;
    overflow-y: auto;
  }

  .menu-list-bgc {
    background-color: var(--sonMenuColor);
    color: var(--fontColor);
    align-items: center;
    padding: 15px;
    cursor: pointer;
  }

  .menuSon-list-bgc {
    margin-top: 5px;
    background-color: var(--headerColor);
    padding: 10px 15px 10px 30px;
    border-radius: 5px;
  }

  .menuSon-list-color {
    background-color: var(--openSonMenuColor);
    color: var(--openSonFontColor);
    border-left: 4px solid;
    cursor: pointer;
  }

  .menuSon-list-color1 {
    color: var(--fontColor);
    padding: 10px 15px 10px 34px;
    cursor: pointer;
  }
  .routerView {
    width: 100%;
    background: var(--viewBackgroundStyle);
    border-radius: 5px;
    height: calc(100% - 20px);
    border: 0;
  }
</style> 

五:运行测试

运行npm run dev





项目地址

gitee.com/beany/myVue

github.com/MyBeany/myV…

写文章不易,如对您有帮助,请帮忙点下star

结尾

添加修改系统主题样式功能已完成,后续功能接下来陆续更新,有问题可以联系我mr_beany@163.com。另求各路大神指点,感谢大家。