官网地址:
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>