/** * 主题状态管理 */ import {changeColor} from '@/components/ele-admin-pro/packages/style/util.js'; import setting from '@/config/setting'; // 不需要本地缓存的state const NO_CACHE_STATE = [ 'collapse', 'tabs', 'homeComponents', 'keepAliveInclude', 'keepAliveExclude', 'tabKeepAlive', 'screenWidth', 'screenHeight' ]; /** * 读取缓存的配置 * @param keyName 缓存的键名 * @returns {Object} */ function getCacheSetting(keyName) { let cache = {}; try { const value = localStorage.getItem(keyName); if (value) { const temp = JSON.parse(value); if (typeof temp === 'object') { cache = temp; } } } catch (e) { console.error(e); } return cache; } /** * 缓存配置 * @param keyName 缓存的键名 * @param key 缓存的配置名 * @param value 缓存的配置名对应的值 */ function cacheSetting(keyName, key, value) { if (NO_CACHE_STATE.includes(key)) { return; } const cache = getCacheSetting(keyName); if (cache[key] !== value) { cache[key] = value; localStorage.setItem(keyName, JSON.stringify(cache)); } } /** * 检查state值以兼容旧版本 * @param key * @param value * @returns */ function checkStateValue(key, value) { if (typeof value === 'number') { if (key === 'sideStyle') { return ['light', 'dark'][value < 2 ? value : 1]; } if (key === 'headStyle') { return ['light', 'dark', 'primary'][value < 3 ? value : 2]; } if (key === 'tabStyle') { return ['default', 'dot', 'card'][value < 3 ? value : 2]; } if (key === 'layoutStyle') { return ['side', 'top', 'mix'][value < 3 ? value : 2]; } } return value; } /** * 获取state * @param setting 默认配置 * @returns {Object} */ function getState(setting) { const state = { // 侧边栏风格: light(亮色), dark(暗色) sideStyle: 'light', // 顶栏风格: light(亮色), dark(暗色), primary(主色) headStyle: 'primary', // 标签页风格: default(默认), dot(圆点), card(卡片) tabStyle: 'default', // 布局风格: side(默认), top(顶栏菜单), mix(混合菜单) layoutStyle: 'side', // 侧边栏菜单风格: default(默认), mix(双排菜单) sideMenuStyle: 'default', // 是否固定侧栏 fixedSidebar: true, // 是否固定顶栏 fixedHeader: false, // 是否固定主体 fixedBody: false, // 内容区域宽度铺满 bodyFull: true, // 是否开启多标签 showTabs: true, // logo是否自适应宽度 logoAutoSize: true, // 侧栏是否多彩图标 colorfulIcon: true, // 侧边栏是否只保持一个子菜单展开 sideUniqueOpen: true, // 是否开启页脚 showFooter: true, // 是否是色弱模式 weakMode: false, // 是否是暗黑模式 darkMode: false, // 主题色 color: null, // 是否折叠侧边栏 collapse: false, // 当前打开的选项卡 tabs: [], // 主页的组件 homeComponents: [], // 需要keep-alive的组件 keepAliveInclude: [], // 不需要keep-alive的组件 keepAliveExclude: [], // 开启多页签是否缓存组件 tabKeepAlive: true, // 屏幕宽度 screenWidth: document.documentElement.clientWidth || document.body.clientWidth, // 屏幕高度 screenHeight: document.documentElement.clientHeight || document.body.clientHeight }; // 读取缓存的配置及默认配置 for (let key in state) { if (!Object.prototype.hasOwnProperty.call(state, key)) { continue; } const cache = getCacheSetting(setting.themeStoreName); if (cache[key] !== undefined) { state[key] = checkStateValue(key, cache[key]); } else if (setting[key] !== undefined) { state[key] = checkStateValue(key, setting[key]); } } // 恢复色弱模式 if (state.weakMode) { changeWeakMode(true); } // 恢复上次主题色 if (state.color || state.darkMode) { window.addEventListener('load', () => { doChangeTheme(state.color, state.darkMode).catch((e) => { console.error(e); }); }); } return state; } /** * 切换主题 * @param value 主题 * @param dark 是否是暗黑模式 * @returns {Promise<>} */ function doChangeTheme(value, dark) { return new Promise((resolve, reject) => { try { changeColor(value, dark); resolve(); } catch (e) { reject(e); } }); } /** * 开关色弱模式 * @param weakMode 是否开启色弱模式 */ function changeWeakMode(weakMode) { const weakClass = 'ele-admin-weak'; if (weakMode) { document.body.classList.add(weakClass); } else { document.body.classList.remove(weakClass); } } /** * 获取需要keep-alive的组件 * @param tabs 页签数据 * @param homeComponents 主页组件 * @returns {any[]} */ function getKeepAliveInclude(tabs, homeComponents) { const components = new Set(); if (tabs) { tabs.forEach((t) => { if (t && t.components && t.components.length) { t.components.forEach((c) => { if (typeof c === 'string' && c) { components.add(c); } }); } }); } if (homeComponents) { homeComponents.forEach((c) => { components.add(c); }); } return Array.from(components); } export default { namespaced: true, state: getState(setting), mutations: { // 修改state值 SET: function (state, obj) { state[obj.key] = obj.value; // 缓存修改的配置 cacheSetting(setting.themeStoreName, obj.key, obj.value); }, // 更新keepAliveInclude UPDATE_KEEP_ALIVE_INCLUDE: function (state) { if (state.showTabs && state.tabKeepAlive) { state.keepAliveInclude = getKeepAliveInclude(state.tabs, state.homeComponents); } else { state.keepAliveInclude = []; } } }, actions: { /** * 修改配置 * @param {commit} * @param obj */ set({commit}, obj) { commit('SET', obj); if (obj.key === 'showTabs' || obj.key === 'tabKeepAlive') { commit('UPDATE_KEEP_ALIVE_INCLUDE'); } }, /** * 切换配置(boolean类型的配置) * @param {commit, state} * @param key 配置名称 */ toggle({commit, state}, key) { commit('SET', {key: key, value: !state[key]}); }, /** * 切换主题色 * @param {commit, state} * @param value 颜色值 * @returns {Promise<>} */ setColor({commit, state}, value) { return new Promise((resolve, reject) => { doChangeTheme(value, state.darkMode).then(() => { commit('SET', {key: 'color', value: value}); return resolve(); }).catch((e) => { reject(e); }); }); }, /** * 切换暗黑模式 * @param {commit, state} * @param value 是否开启暗黑模式 * @returns {Promise<>} */ setDarkMode({commit, state}, value) { return new Promise((resolve, reject) => { doChangeTheme(state.color, value).then(() => { commit('SET', {key: 'darkMode', value: value}); return resolve(); }).catch((e) => { reject(e); }); }); }, /** * 切换色弱模式 * @param {commit} * @param value 是否开启色弱模式 * @returns {Promise<>} */ setWeakMode({commit}, value) { return new Promise((resolve) => { changeWeakMode(value); commit('SET', {key: 'weakMode', value: value}); resolve(); }); }, /** * 添加tab * @param {commit, state} * @param obj {{key: String, path: String, fullPath: String, title: String}} */ tabAdd({commit, state}, obj) { if (!obj.key) { obj.key = obj.fullPath || obj.path; } const i = state.tabs.findIndex((d) => d.key === obj.key); if (i === -1) { commit('SET', {key: 'tabs', value: state.tabs.concat([obj])}); } else if (obj.fullPath !== state.tabs[i].fullPath) { commit('SET', {key: 'tabs', value: state.tabs.slice(0, i).concat([obj]).concat(state.tabs.slice(i + 1))}); } commit('UPDATE_KEEP_ALIVE_INCLUDE'); }, /** * 移除指定tab * @param commit * @param state * @param key {String} * @returns {Promise} */ tabRemove({commit, state}, key) { return new Promise((resolve) => { let index = -1, lastIndex = -1, lastPath, last; for (let i = 0; i < state.tabs.length; i++) { if (state.tabs[i].key === key || state.tabs[i].fullPath === key) { index = i; break; } lastIndex = i; last = state.tabs[i]; lastPath = last.fullPath; } commit('SET', {key: 'tabs', value: state.tabs.filter((d, i) => i !== index)}); commit('UPDATE_KEEP_ALIVE_INCLUDE'); resolve({lastIndex: lastIndex, lastPath: lastPath, last: last}); }); }, /** * 移除所有tab * @param commit */ tabRemoveAll({commit}) { commit('SET', {key: 'tabs', value: []}); commit('UPDATE_KEEP_ALIVE_INCLUDE'); }, /** * 移除左侧tab * @param commit * @param state * @param key {String} */ tabRemoveLeft({commit, state}, key) { for (let i = 0; i < state.tabs.length; i++) { if (state.tabs[i].key === key) { commit('SET', {key: 'tabs', value: state.tabs.slice(i)}); commit('UPDATE_KEEP_ALIVE_INCLUDE'); break; } } }, /** * 移除右侧tab * @param commit * @param state * @param key {String} */ tabRemoveRight({commit, state}, key) { for (let i = 0; i < state.tabs.length; i++) { if (state.tabs[i].key === key) { commit('SET', {key: 'tabs', value: state.tabs.slice(0, i + 1)}); commit('UPDATE_KEEP_ALIVE_INCLUDE'); break; } } }, /** * 移除其他tab * @param commit * @param state * @param key {String} */ tabRemoveOther({commit, state}, key) { commit('SET', {key: 'tabs', value: state.tabs.filter((d) => d.key === key)}); commit('UPDATE_KEEP_ALIVE_INCLUDE'); }, /** * 修改指定tab * @param commit * @param state * @param obj {{path: String, title: String, fullPath: String, closable: Boolean}} */ tabSetTitle({commit, state}, obj) { let i = -1; if (obj.fullPath) { i = state.tabs.findIndex((d) => d.fullPath === obj.fullPath); } else if (obj.path) { i = state.tabs.findIndex((d) => d.path === obj.path); } if (i !== -1) { const data = Object.assign({}, state.tabs[i]); if (typeof obj.title === 'string' && obj.title) { data.title = obj.title; } if (typeof obj.closable === 'boolean') { data.closable = obj.closable; } const tabs = state.tabs.slice(0, i).concat([data]).concat(state.tabs.slice(i + 1)); commit('SET', {key: 'tabs', value: tabs}); } }, /** * 设置主页的组件名称 * @param {commit, state} * @param components {Array} */ setHomeComponents({commit}, components) { commit('SET', {key: 'homeComponents', value: components}); commit('UPDATE_KEEP_ALIVE_INCLUDE'); }, /** * 设置不需要keep-alive的组件 * @param commit * @param value {Array} */ setKeepAliveExclude({ commit }, value) { console.log(value); commit('SET', {key: 'keepAliveExclude', value: value}); }, /** * 更新屏幕尺寸 * @param {commit, state} */ updateScreen({commit, state}) { const w = document.documentElement.clientWidth || document.body.clientWidth, h = document.documentElement.clientHeight || document.body.clientHeight; if (w !== state.screenWidth) { commit('SET', {key: 'screenWidth', value: w}); } if (h !== state.screenHeight) { commit('SET', {key: 'screenHeight', value: h}); } } } };