Vue 自定义主题、logo如何监听其变化及实时更新(Vuex状态管理)

官网地址:

Vuex官网 首先了解Vuex,下面内容不具体描述Vuex基础知识。



问题描述:

在项目中遇到需求:自定义系统的logo、title、主题颜色等,此时修改这些系统配置时会涉及到同步更新问题。例如在系统配置管理页面更新系统logo,则系统logo自动更新。(意思就是在vue项目中更新logo写在A组件,logo在B组件,A中logo值发生改变,无法实时更新B中logo,需要使用vue提供的vuex技术)

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。



结构目录:

store
    ├── index.js          # 我们组装模块并导出 store 的地方
    └── modules
        ├── user.js       # 用户模块
        └── conmmon.js    # 公共模块
 

 index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import common from './modules/common'

Vue.use(Vuex)
const store = new Vuex.Store({
  modules: {
    user,
    common
  }
})

export default store

user.js

import {getStore, setStore} from '@/util/store'
import {getSystemInfo} from '@/api/home/systemConfig'

const user = {
  state: {
    system_info: getStore({
			name: 'system_info'
		}) || undefined,
  },
  actions: {
    // 获取系统信息
    GetSystemInfo({commit}) {
      return new Promise(resolve => {
        getSystemInfo().then(res => {
          const data = res.data.data
          commit('SET_SYSTEM_INFO', data)
          resolve(data)
        }).catch(error => {
          reject(error)
        })
      })
    },
  },
  mutations: {
    // 系统信息
    SET_SYSTEM_INFO: (state, system_info) => {
			state.system_info = system_info
			setStore({
				name: 'system_info',
				content: system_info,
				type: 'session'
			})
		}
  }

}
export default user


导航(如何监听数据变化)

<template>
	<div class="container">
		<div class="font-bold title-style">
		    <img v-if="logo" class="logo" :src="logo" alt="logo">
			<span style="font-size: 25px;" >{{title}}</span>
		</div>
	</div>
</template>

<script>
	import {mapState,mapGetters} from 'vuex'
	export default {
		data() {
			return {
				logo:undefined,
				title:'数据门户管理系统',
				color:undefined
			}
		},
		computed: {
			...mapState({
				systemInfo: state => state.user.system_info
			})
		},
		created() {
            //加载系统信息
			this.$store.dispatch('GetSystemInfo').then((data) => {})
			this.getSystemInfo(this.systemInfo)
		},
		methods: {
			//配置系统信息 logo、title、color
			getSystemInfo(data) {
				let logo = data.sysLogo
				let title = data.sysTitle
				let color = data.sysColor
				if(logo) {
					this.logo = logo
				}
				if(title) {
					this.title = JSON.parse(title)[1].maName
				}
				if(color) {
					this.color = JSON.parse(color)
					let root = document.querySelector(":root");
					for(let i in this.color) {
						root.style.setProperty(this.color[i].text, this.color[i].color);
					}
				}
			}
		},
		watch: {
			// 监听路由变化
			'$route.path': {
				handler(routePath) {
					//更换颜色后未保存则本地存储颜色信息,加载原有颜色
					var getVal = localStorage.getItem('color');
					if( getVal !== null ){
						this.getSystemInfo(this.systemInfo)
						// 清除本地缓存
						localStorage.removeItem('color');
					}
				},
				immediate: true
			},
			// 监听系统配置信息变化
			systemInfo:function(val) {
				this.getSystemInfo(val)
			}
		}
	}
</script>

修改主题色页面具体代码

<template>
	<div class="color">
		<el-row style="margin-bottom:20px;">
			<div class="float-right" v-if="visible">
				<el-button type="primary"  @click="saveHandle()">保存</el-button>
				<el-button type="primary"  @click="reset()">重置</el-button>
			</div>
		</el-row>
		<el-table
			:data="dataList"
			style="width: 100%;font-size:16px;">
			<el-table-column
				align="center"
				header-align="center"
				label="区域名称"
				prop="name">
			</el-table-column>
			<el-table-column label="颜色" header-align="center" align="center">
				<template slot-scope="scope">
					<el-color-picker
						v-model="scope.row.color"
						@change="changeHandle(scope.row.text)">
					</el-color-picker>
				</template>
			</el-table-column>
		</el-table>
	</div>
</template>

<script>
	import { mapState } from 'vuex'
	import {addSystemInfo} from '@/api/home/systemConfig'
	export default {
		data() {
			return {
				visible:false,//颜色是否变更
				dataList: [{
					name:'顶部导航栏默认填充色',
					color:'#063972',
					text:'--navBgColor'
				},
				{
					name:'顶部导航栏默认字体颜色',
					color:'#fff',
					text:'--navTextColor'
				},
				{
					name:'顶部导航栏选中区域填充色',
					color:'#15559D',
					text:'--navActiveBgColor'
				},
				{
					name:'顶部导航栏选中区域字体颜色',
					color:'#fff',
					text:'--navActiveTextColor'
				},
				{
					name:'侧边导航栏默认填充色',
					color:'rgba(20, 85, 157, 100)',
					text:'--bgColor'
				},
				{
					name:'侧边导航栏默认字体颜色',
					color:'#fff',
					text:'--textColor'
				},
				{
					name:'侧部导航栏选中区域填充色',
					color:'#F5F5F5',
					text:'--activeBgColor'
				},
				{
					name:'侧导航导航栏选中区域字体颜色',
					color:'#063972',
					text:'--activeTextColor'
				},
				{
					name:'页脚填充色',
					color:'#19233C',
					text:'--footerBgColor'
				},
				{
					name:'页脚字体颜色',
					color:'#fff',
					text:'--footerTextColor'
				}]
			}
		},
		computed: {
			...mapState({
				systemInfo: state => state.user.system_info
			}),
		},
		created() {
		},
		methods: {
			init() {
				this.getDataList()
				this.visible = false
			},
			//查询列表
			getDataList() {
				let data = Object.assign({},this.systemInfo)
				let color = data.sysColor
				if(color) {
					this.dataList = JSON.parse(color)
				}
				let root = document.querySelector(":root");
				for(let i in this.dataList) {
					root.style.setProperty(this.dataList[i].text, this.dataList[i].color);
				}
			},
			// 重置
			reset() {
				this.visible = false
				this.getDataList()
			},
			//改变颜色
			changeHandle(partColor) {
				this.visible = true
				let root = document.querySelector(":root");
				for(let i in this.dataList) {
					root.style.setProperty(this.dataList[i].text, this.dataList[i].color);
				}
				//改变颜色但不保存时,将该颜色存储到本地来判断
				localStorage.setItem('color', JSON.stringify(this.dataList));
			},
			// 保存
			saveHandle() {
				let data = {
					sysTitle: this.systemInfo.sysTitle,
					sysLogo: this.systemInfo.sysLogo,
					sysColor: JSON.stringify(this.dataList)
				}
				addSystemInfo(data).then(res => {
					this.$store.commit('SET_SYSTEM_INFO', data)
					this.visible = false
					this.$message.success('保存成功')
					// 清除本地缓存
					localStorage.removeItem('color');
				}).catch(error => {
					this.$message.success('保存失败')
				});
			}
		},
	}
</script>

<style lang="scss" scoped>
	
	.color >>> .el-color-picker--small .el-color-picker__trigger {
		width: 100px;
	}
</style>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值