赞
踩
今天分享的是基于element-ui的主题换肤功能
效果如动图:
需求描述:根据客户的个人喜好,切换不同颜色风格的主题。
ps:第一张图红色框内为自定义主题内,相关组件的颜色,设置好后点击下载,下载好的文件包含css文件和字体文件。第二张图就是配置好对应颜色的主题静态文件。
<template> <div class="color" @click.stop> <el-scrollbar style="height: 100%;"> <div class="dropMeau"> <div class="headerLine"> 经典皮肤 {{getSkinName}} </div> <div class="wrapCell"> <div class="colorSkinWrap" v-for="(item,i,k) in themeList"> <span finger @click="changeColor(item.themeName)" :style="{background: computedBgc(item) }" class="colorSkin " :class="{active:getSkinName==item.themeName}" style=" background: #042663;"> <span class="icon-yiwancheng iconfont"></span> </span> <p class="name">{{item.themeName}}</p> </div> </div> </div> </el-scrollbar> </div> </template> <script> import themeList from '@libs/css/style.js' // 定义颜色的js文件,里面包含了颜色,特殊的图片地址 import { mixin } from "@libs/mixs.js"; import { mapActions, mapGetters } from 'vuex' export default { name: "messageQuick", mixins: [mixin], data() { return { themeName: '', themeList, } }, computed: { ...mapGetters('info', ['getSkinName']), // 存在vux中的颜色变量属性 }, created() { }, methods: { ...mapActions('info', [ 'actionSkinChange' ]), computedBgc(item) { if (item.spec) { return `${item.style['--primary-color']} url('${item.showBox}')` } else { return item.style['--primary-color'] } }, changeColor(name) { //主题 跳转页面判断皮肤换肤 if (name != this.getSkinName) { this.axios({ url: "/service-user-app/app/user/config/skin/peeler", // 保存用户的选择接口 method: "post", params: { colour: name }, interface: 1 }).then(res => { let data = res.data if (data.code == 0) { this.actionSkinChange(name) // 更改vux中的默认颜色值 this.setStyleRoot(name, themeList) // 更改主题色 } }) } } }, }
export default [ { "themeName": "绀青", // gangqing "src": "/static/theme/gangqing/index.css", "style": { "--primary-color": "#245BBF", "--table-header-bcolor": "#F7F7F7", "--primary-mix05": "#CFD5E0", "--primary-mix1": "#CFD5E0", "--primary-mix2": "#BDC8DC", "--primary-mix3": "#A9BAD9", "--primary-mix4": "#97ADD5", "--primary-mix5": "#849FD2", "--primary-mix6": "#7091CD", "--primary-mix7": "#5D83CA", "--primary-mix8": "#4A76C6", "--primary-mix9": "#3769C3", /* 导航栏 */ "--nav-backgroud-color": "#042663", "--nav-ul-backgroud-color": "#fff", "--nav-ul-font-color": "#333", "--nav-ul-active-backgroud-color": "#D8E6FF", "--nav-ul-active-font-color": "#333", /* 头部颜色*/ "--header-backgroud-color": "#042663", } }, // todo 加图片 { "themeName": "紫棠", // zitang "spec":true, "showBox":'/static/img/zitang.png', "src": "/static/theme/zitang/index.css", "style": { "--primary-color": "#78359A", "--table-header-bcolor": "#F7F7F7", "--primary-mix05": "#F1EAF5", "--primary-mix1": "#F1EAF5", "--primary-mix2": "#E4D6EB", "--primary-mix3": "#D6C2E0", "--primary-mix4": "#C9AED6", "--primary-mix5": "#BB99CC", "--primary-mix6": "#AE85C2", "--primary-mix7": "#A071B8", "--primary-mix8": "#935DAE", "--primary-mix9": "#8548A3", /* 导航栏 */ // "--nav-backgroud-color": "#531659", "--nav-backgroud-color": "#531659 url('/static/img/zitang1.jpg')", "--nav-ul-backgroud-color": "#fff", "--nav-ul-font-color": "#333", "--nav-ul-active-backgroud-color": "#F6EAFC", "--nav-ul-active-font-color": "#333", /* 头部颜色*/ // "--header-backgroud-color": "#531659", "--header-backgroud-color": "#531659 url('/static/img/zitang2.jpg')", } }, ]
ps:因为代码太多,所以抽成了js文件,我只取了其中两种有区别颜色的代码段(完整的有11种,和页面上的一样),有 “spec”:true,属性的颜色,就是带有花纹的主题,而不是普通的素颜色主题。
import Vue from "vue" import {isHiddenPhone} from '@libs/http/vuex_http' export let info = { namespaced:true, state:{ skinName:'', _radio:null, // '0':'1' timestamp:new Date().getTime() -0 + 1800000 }, getters: { radio: state => state.radio, getSkinName:state => state.skinName||'绀青',//默认皮肤 }, mutations: { changeSkin(state, data) { state.skinName = data }, changeHiddenStatus(state, data) { state._radio = data }, }, actions: { actionSkinChange({ commit,getters},res){ // 修改state里面的skinName值 commit('changeSkin',res) }, httpForIsHiddenPhone ({ commit,getters}) { isHiddenPhone(Vue).then(res=>{ if (res.data.code == '0') { // 是否隐藏 true 需要隐藏电话号码中间四位false 无需隐藏 commit('changeHiddenStatus',res.data.data?'0':'1') } }) } } }
/** * @description: 设置皮肤 * @param {themeName} 自定义的样式名称 * @return {*} */ setStyleRoot(themeName, themeList = []) { let arr = themeList.filter(q => q.themeName == themeName) if (arr.length == 0) return console.error('未设置样式皮肤') let item = arr[0] let root = [] for (let i in item.style) { root.push(i + `:` + item.style[i]) } let test = `:root{${root.join(';')}}` // 拼接为样式代码, // :root 这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示 <html> 元素,除了优先级更高之外,与 html 选择器相同。 this.addNode(test, item.src) }, /** * @description: 添加节点皮肤节点 * @param {test} 设置:root 样式 * @param {url} 插入的外链 * @return {*} */ addNode(test, url) { let styleNode = document.getElementById('theme') let linkNode = document.getElementById('linkTheme') if (styleNode) { // 如果有节点就改变,没有就创建 styleNode.innerHTML = test document.getElementsByTagName('body')[0].appendChild(styleNode) if(linkNode.getAttribute('href') != url) { linkNode.setAttribute('href', url) } } else { styleNode = document.createElement('style') linkNode = document.createElement('link') styleNode.setAttribute('id', 'theme') linkNode.setAttribute('href', url) linkNode.setAttribute('id', "linkTheme") linkNode.setAttribute('rel', "stylesheet") linkNode.setAttribute('type', "text/css") styleNode.innerHTML = test document.getElementsByTagName('body')[0].appendChild(styleNode) document.getElementsByTagName('head')[0].appendChild(linkNode) } },
@primaryColor: var(--primary-color,#245BBF); //主题色 var全局变量,--primary-color没有值的话,就是默认颜色#245BBF //色值待替换 混合 白色百分比 @primaryColorMix05:var(--primary-mix05,#F3F6FC); @primaryColorMix1:var(--primary-mix1,#E8EEF9); @primaryColorMix2:var(--primary-mix2,#D3DEF2); @primaryColorMix3:var(--primary-mix3,#BCCDEC); @primaryColorMix4:var(--primary-mix4,#A7BDE5); @primaryColorMix5:var(--primary-mix5,#91ACDF); @primaryColorMix6:var(--primary-mix6,#7B9CDF); @primaryColorMix7:var(--primary-mix7,#658BD2); @primaryColorMix8:var(--primary-mix8,#4f7BCB); @primaryColorMix9:var(--primary-mix9,#396BC5); @borderColor_base: #e5e5e5; //一般边框色值 @tableBColor_base:var(--table-header-bcolor,#F7F7F7); //表格头部颜色 /* 导航栏色值 */ @navBackgroudColor: var(--nav-backgroud-color, #ffffff); //@navBackgroudImg: var(--nav-backgroud-img); @navUlBackgroudColor: var(--nav-ul-backgroud-color, #ffffff); @navUlFontColor: var(--nav-ul-font-color, #ffffff); @navUlActiveBackgroudColor: var(--nav-ul-active-backgroud-color, #ffffff); @navUlActiveFontColor: var(--nav-ul-active-font-color, #ffffff); @headerBackgroudColor: var(--header-backgroud-color, #ffffff); //@headerBackgroudImg: var(--header-backgroud-img);
ps:所有与主题颜色相关的color代码都要用@*****,例如某个css样式:
.active {
font-size: 14px;
font-weight: 700;
color: @primaryColor;
border-bottom: 1px solid @primaryColor;
}
getSkin(){
this.axios({
url: "/service-user-app/app/user/config/select-by-userId",
method: "get",
interface:1
}).then(res => {
let data = res.data
if (data.code == 0) {
if(!data.data)return
let obj = JSON.parse(data.data.val)
this.actionSkinChange(obj.colour)//存起来
this.setStyleRoot(obj.colour, themeList) //改变皮肤
}
})
},
ps:接口返回:val: “{“platformSource”:22,“colour”:“绀青”}”,所以要反序列化一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。