From 551aa111a17e9e9860e28d4181bca6edac56b8fa Mon Sep 17 00:00:00 2001 From: liyang <1711467488@qq.com> Date: Fri, 10 Aug 2018 13:49:54 +0800 Subject: [PATCH] page Former-commit-id: 1801c7a5909d5415b360a996d4ecab23280b1076 [formerly 1801c7a5909d5415b360a996d4ecab23280b1076 [formerly 1801c7a5909d5415b360a996d4ecab23280b1076 [formerly 1801c7a5909d5415b360a996d4ecab23280b1076 [formerly 209999b1c78ca63880406cb2b633c3560aae0eba [formerly 54edc3b4bd966e2496564198d59ff84fe9ba0b25]]]]] Former-commit-id: ad91a7092b963def0579ecc2011e578e87a8ecd5 Former-commit-id: fb96644ac016362df708618fafef872b7bc2567c Former-commit-id: 257c0b84b8069b3ccb8ddc53e965a974fca01189 [formerly 6954456a39b73136a14f80b0747aea90a694c9a5] Former-commit-id: 99c7481e576afeac70fff4effa7e57f6b17cb79d Former-commit-id: cfddcdd7f760c61e4abe02159a75d484ad6c6e63 Former-commit-id: 06d4e8cf94bd8c24fa167d77f843c93541afb5e6 Former-commit-id: ef6879d28d953c827184c4d5caa6c7fef6b2326f Former-commit-id: 1f1114b417621402ec7d9d3540b305563fb140ec --- .../header-aside/components/tabs/index.vue | 35 ++- src/layout/header-aside/layout.vue | 2 +- src/libs/db.js | 2 +- src/main.js | 2 +- src/pages/demo/playground/store/sys/index.vue | 17 +- src/router/index.js | 2 +- src/store/modules/d2admin/index.js | 99 ++++++ .../modules/d2admin/index.js.REMOVED.git-id | 1 - src/store/modules/d2admin/modules/account.js | 2 +- src/store/modules/d2admin/modules/page.js | 294 ++++++++++++++++++ 10 files changed, 424 insertions(+), 32 deletions(-) create mode 100644 src/store/modules/d2admin/index.js delete mode 100644 src/store/modules/d2admin/index.js.REMOVED.git-id create mode 100644 src/store/modules/d2admin/modules/page.js diff --git a/src/layout/header-aside/components/tabs/index.vue b/src/layout/header-aside/components/tabs/index.vue index 36b8753e..5180877b 100644 --- a/src/layout/header-aside/components/tabs/index.vue +++ b/src/layout/header-aside/components/tabs/index.vue @@ -12,14 +12,14 @@ @@ -82,17 +82,18 @@ export default { } }, computed: { - ...mapState('d2admin', [ - 'pageOpenedList', - 'pageCurrent' + ...mapState('d2admin/page', [ + 'opened', + 'current' ]) }, methods: { - ...mapMutations('d2admin', [ - 'tagCloseLeft', - 'tagCloseRight', - 'tagCloseOther', - 'tagCloseAll' + ...mapMutations('d2admin/page', [ + 'close', + 'closeLeft', + 'closeRight', + 'closeOther', + 'closeAll' ]), /** * @description 右键菜单功能点击 @@ -136,16 +137,16 @@ export default { } switch (command) { case 'left': - this.tagCloseLeft(params) + this.closeLeft(params) break case 'right': - this.tagCloseRight(params) + this.closeRight(params) break case 'other': - this.tagCloseOther(params) + this.closeOther(params) break case 'all': - this.tagCloseAll(this) + this.closeAll(this) break default: this.$message.error('无效的操作') @@ -156,14 +157,14 @@ export default { * @description 接收点击关闭控制上按钮的事件 */ handleControlBtnClick () { - this.tagCloseAll(this) + this.closeAll(this) }, /** * @description 接收点击 tab 标签的事件 */ handleClick (tab, event) { // 找到点击的页面在 tag 列表里是哪个 - const page = this.pageOpenedList.find(page => page.name === tab.name) + const page = this.opened.find(page => page.name === tab.name) const { name, params, query } = page if (page) { this.$router.push({ name, params, query }) @@ -174,7 +175,7 @@ export default { */ handleTabsEdit (tagName, action) { if (action === 'remove') { - this.$store.commit('d2admin/tagClose', { + this.close({ tagName, vm: this }) diff --git a/src/layout/header-aside/layout.vue b/src/layout/header-aside/layout.vue index 58e0e690..1cf19fbf 100644 --- a/src/layout/header-aside/layout.vue +++ b/src/layout/header-aside/layout.vue @@ -83,7 +83,7 @@ export default { asideCollapse: state => state.menu.asideCollapse }), ...mapGetters('d2admin', { - keepAliveInclude: 'keepAliveInclude', + keepAliveInclude: 'page/keepAliveInclude', themeActiveSetting: 'theme/activeSetting' }), /** diff --git a/src/libs/db.js b/src/libs/db.js index 1161022d..78914048 100644 --- a/src/libs/db.js +++ b/src/libs/db.js @@ -11,7 +11,7 @@ db.defaults({ sys: {}, db: {}, // 旧 - pageOpenedList: [], + opened: [], database: [], databasePublic: {} }).write() diff --git a/src/main.js b/src/main.js index 8ef9c4fe..5776fc6b 100644 --- a/src/main.js +++ b/src/main.js @@ -102,7 +102,7 @@ new Vue({ }) } push(frameInRoutes) - this.$store.commit('d2admin/pagePoolSet', pool) + this.$store.commit('d2admin/page/poolSet', pool) } } }).$mount('#app') diff --git a/src/pages/demo/playground/store/sys/index.vue b/src/pages/demo/playground/store/sys/index.vue index 5708a447..321fcb3f 100644 --- a/src/pages/demo/playground/store/sys/index.vue +++ b/src/pages/demo/playground/store/sys/index.vue @@ -100,8 +100,8 @@
+ :data="pageopened" + :options="{ rootObjectKey: 'pageopened', maxDepth: 1 }"/>
@@ -149,15 +149,14 @@ export default { // 全屏 fullscreenActive: state => state.fullscreen.active, // 灰度模式 - grayActive: state => state.gray.active + grayActive: state => state.gray.active, + // tag 池 + pagePool: state => state.page.pool, + pageCurrent: state => state.page.current, + pageopened: state => state.page.opened }), - ...mapState('d2admin', [ - 'pagePool', - 'pageOpenedList', - 'pageCurrent' - ]), ...mapGetters('d2admin', { - keepAliveInclude: 'keepAliveInclude', + keepAliveInclude: 'page/keepAliveInclude', themeActiveSetting: 'theme/activeSetting' }) } diff --git a/src/router/index.js b/src/router/index.js index d715ede0..b3766ab0 100755 --- a/src/router/index.js +++ b/src/router/index.js @@ -42,7 +42,7 @@ router.afterEach(to => { const app = router.app const { name, params, query } = to // 多页控制 打开新的页面 - app.$store.commit('d2admin/pageOpenNew', { name, params, query }) + app.$store.commit('d2admin/page/open', { name, params, query }) // 更改标题 util.title(to.meta.title) }) diff --git a/src/store/modules/d2admin/index.js b/src/store/modules/d2admin/index.js new file mode 100644 index 00000000..763d92c3 --- /dev/null +++ b/src/store/modules/d2admin/index.js @@ -0,0 +1,99 @@ +import get from 'lodash.get' +import set from 'lodash.set' +import utilLib from '@/libs/util.js' +import dbLib from '@/libs/db.js' + +// 模块 + +import db from './modules/db' +import releases from './modules/releases' +import user from './modules/user' +import menu from './modules/menu' +import theme from './modules/theme' +import log from './modules/log' +import account from './modules/account' +import fullscreen from './modules/fullscreen' +import ua from './modules/ua' +import gray from './modules/gray' +import page from './modules/page' + +export default { + namespaced: true, + modules: { + db, + releases, + user, + menu, + theme, + log, + account, + fullscreen, + ua, + gray, + page + }, + mutations: { + /** + * @class 通用工具 + * @description 将 state 中某一项存储到数据库 如果已经有的话就更新数据 需要 uuid + * @param {Object} state vuex state + * @param {String} key key name + */ + utilVuex2DbByUuid (state, key) { + const dbKey = key.split('.')[key.split('.').length - 1] + const row = dbLib.get(dbKey).find({uuid: utilLib.cookies.get('uuid')}) + const value = get(state, key, '') + if (row.value()) { + row.assign({ value }).write() + } else { + dbLib.get(dbKey).push({ + uuid: utilLib.cookies.get('uuid'), + value + }).write() + } + }, + /** + * @class 通用工具 + * @description 从数据库取值到 vuex 需要 uuid + * @param {Object} state vuex state + * @param {Object} param key 键名, defaultValue 取值失败默认值, handleFunction 处理函数 + */ + utilDb2VuexByUuid (state, { key, defaultValue, handleFunction }) { + const dbKey = key.split('.')[key.split('.').length - 1] + const row = dbLib.get(dbKey).find({uuid: utilLib.cookies.get('uuid')}).value() + const handle = handleFunction || (res => res) + set(state, key, row ? handle(row.value) : defaultValue) + }, + /** + * @class 通用工具 + * @description 将 state 中某一项存储到数据库 如果已经有的话就更新数据 不需要 uuid 所有用户共享 + * @param {Object} state vuex state + * @param {String} key key name + */ + utilVuex2Db (state, key) { + const dbKey = key.split('.')[key.split('.').length - 1] + const row = dbLib.get(dbKey).find({pub: 'pub'}) + const value = get(state, key, '') + if (row.value()) { + row.assign({ value }).write() + } else { + dbLib.get(dbKey).push({ + pub: 'pub', + value + }).write() + } + }, + /** + * @class 通用工具 + * @description 从数据库取值到 vuex 不需要 uuid 所有用户共享 + * @param {Object} state vuex state + * @param {Object} param key 键名, defaultValue 取值失败时的默认值, handleFunction 处理函数 + */ + utilDb2Vuex (state, { key, defaultValue, handleFunction }) { + const dbKey = key.split('.')[key.split('.').length - 1] + const row = dbLib.get(dbKey).find({pub: 'pub'}).value() + const handle = handleFunction || (res => res) + set(state, key, row ? handle(row.value) : defaultValue) + } + } +} diff --git a/src/store/modules/d2admin/index.js.REMOVED.git-id b/src/store/modules/d2admin/index.js.REMOVED.git-id deleted file mode 100644 index d2d9c661..00000000 --- a/src/store/modules/d2admin/index.js.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -03c3404e1d1584485b9a7b73671b1dd1d17a0e14 \ No newline at end of file diff --git a/src/store/modules/d2admin/modules/account.js b/src/store/modules/d2admin/modules/account.js index 6f117dd5..6db6da07 100644 --- a/src/store/modules/d2admin/modules/account.js +++ b/src/store/modules/d2admin/modules/account.js @@ -97,7 +97,7 @@ export default { // DB -> store 加载主题 this.commit('d2admin/theme/load') // DB -> store 数据库加载上次退出时的多页列表 - this.commit('d2admin/pageOpenedListLoad') + this.commit('d2admin/page/openedLoad') // DB -> store 数据库加载这个用户之前设置的侧边栏折叠状态 this.commit('d2admin/menu/asideCollapseLoad') } diff --git a/src/store/modules/d2admin/modules/page.js b/src/store/modules/d2admin/modules/page.js new file mode 100644 index 00000000..c7556b4e --- /dev/null +++ b/src/store/modules/d2admin/modules/page.js @@ -0,0 +1,294 @@ +const pageOpenedDefult = { + name: 'index', + meta: { + title: '首页', + requiresAuth: false + } +} + +export default { + namespaced: true, + state: { + // 可以在多页 tab 模式下显示的页面 + pool: [], + // 当前显示的多页面列表 + opened: [ + pageOpenedDefult + ], + // 当前页面 + current: '' + }, + getters: { + /** + * @description 从当前所有打开的多标签页里返回需要缓存的页面 name + * @param {*} state vuex state + */ + keepAliveInclude (state) { + return state.opened.filter(item => { + if (item.meta) { + if (item.meta.notCache) { + return false + } + } + return true + }).map(e => e.name) + } + }, + mutations: { + /** + * @class current + * @description 打开一个新的页面 + * @param {Object} state vuex state + * @param {Object} param { name, params, query } 路由信息 + */ + open (state, { name, params, query }) { + // 已经打开的页面 + let opened = state.opened + // 判断此页面是否已经打开 并且记录位置 + let pageOpendIndex = 0 + const pageOpend = opened.find((page, index) => { + const same = page.name === name + pageOpendIndex = same ? index : pageOpendIndex + return same + }) + if (pageOpend) { + // 页面以前打开过 但是新的页面可能 name 一样,参数不一样 + this.commit('d2admin/page/openedUpdateItem', { + index: pageOpendIndex, + params, + query + }) + } else { + // 页面以前没有打开过 + let page = state.pool.find(t => t.name === name) + if (page) { + this.commit('d2admin/page/add', { tag: page, params, query }) + } + } + this.commit('d2admin/page/currentSet', name) + }, + /** + * @class current + * @description 设置当前激活的页面 name + * @param {Object} state vuex state + * @param {String} name new name + */ + currentSet (state, name) { + state.current = name + }, + /** + * @class opened + * @description 更新页面列表上的某一项 + * @param {Object} state vuex state + * @param {Object} param { index, params, query } 路由信息 + */ + openedUpdateItem (state, { index, params, query }) { + // 更新页面列表某一项 + let page = state.opened[index] + page.params = params || page.params + page.query = query || page.query + state.opened.splice(index, 1, page) + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + }, + /** + * @class opened + * @description 从数据库载入分页列表 + * @param {Object} state vuex state + */ + openedLoad (state) { + this.commit('d2admin/utilDb2VuexByUuid', { + key: 'opened', + defaultValue: [ + pageOpenedDefult + ], + handleFunction (res) { + // 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签 + // 以 name 字段为准 + // 如果页面过多的话可能需要优化算法 + // 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效 + const valid = [] + // 处理数据 + return res.map(opened => { + // 忽略首页 + if (opened.name === 'index') { + valid.push(1) + return opened + } + // 尝试在所有的支持多标签页的页面里找到 name 匹配的页面 + const find = state.page.pool.find(item => item.name === opened.name) + // 记录有效或无效信息 + valid.push(find ? 1 : 0) + // 返回合并后的数据 新的覆盖旧的 + // 新的数据中一般不会携带 params 和 query, 所以旧的参数会留存 + return Object.assign({}, opened, find) + }).filter((opened, index) => valid[index] === 1) + } + }) + }, + /** + * @class opened + * @description 新增一个 tag (打开一个页面) + * @param {Object} state vuex state + * @param {Object} param new tag info + */ + add (state, { tag, params, query }) { + // 设置新的 tag 在新打开一个以前没打开过的页面时使用 + let newTag = tag + newTag.params = params || newTag.params + newTag.query = query || newTag.query + // 添加进当前显示的页面数组 + state.opened.push(newTag) + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + }, + /** + * @class opened + * @description 关闭一个 tag (关闭一个页面) + * @param {Object} state vuex state + * @param {Object} param { tagName: 要关闭的标签名字, vm: vue } + */ + close (state, { tagName, vm }) { + // 下个新的页面 + let newPage = state.opened[0] + const isCurrent = state.current === tagName + // 如果关闭的页面就是当前显示的页面 + if (isCurrent) { + // 去找一个新的页面 + let len = state.opened.length + for (let i = 1; i < len; i++) { + if (state.opened[i].name === tagName) { + if (i < len - 1) { + newPage = state.opened[i + 1] + } else { + newPage = state.opened[i - 1] + } + break + } + } + } + // 找到这个页面在已经打开的数据里是第几个 + const index = state.opened.findIndex(page => page.name === tagName) + if (index >= 0) { + state.opened.splice(index, 1) + } + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + // 最后需要判断是否需要跳到首页 + if (isCurrent) { + const { name = '', params = {}, query = {} } = newPage + let routerObj = { + name, + params, + query + } + vm.$router.push(routerObj) + } + }, + /** + * @class opened + * @description 关闭当前标签左边的标签 + * @param {Object} state vuex state + * @param {Object} param { pageSelect: 当前选中的tagName, vm: vue } + */ + closeLeft (state, { pageSelect, vm } = {}) { + const pageAim = pageSelect || state.current + let currentIndex = 0 + state.opened.forEach((page, index) => { + if (page.name === pageAim) { + currentIndex = index + } + }) + if (currentIndex > 0) { + state.opened.splice(1, currentIndex - 1) + } + state.current = pageAim + if (vm && vm.$route.name !== pageAim) { + vm.$router.push({ + name: pageAim + }) + } + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + }, + /** + * @class opened + * @description 关闭当前标签右边的标签 + * @param {Object} state vuex state + * @param {Object} param { pageSelect: 当前选中的tagName, vm: vue } + */ + closeRight (state, { pageSelect, vm } = {}) { + const pageAim = pageSelect || state.current + let currentIndex = 0 + state.opened.forEach((page, index) => { + if (page.name === pageAim) { + currentIndex = index + } + }) + state.opened.splice(currentIndex + 1) + state.current = pageAim + if (vm && vm.$route.name !== pageAim) { + vm.$router.push({ + name: pageAim + }) + } + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + }, + /** + * @class opened + * @description 关闭当前激活之外的 tag + * @param {Object} state vuex state + * @param {Object} param { pageSelect: 当前选中的tagName, vm: vue } + */ + closeOther (state, { pageSelect, vm } = {}) { + const pageAim = pageSelect || state.current + let currentIndex = 0 + state.opened.forEach((page, index) => { + if (page.name === pageAim) { + currentIndex = index + } + }) + if (currentIndex === 0) { + state.opened.splice(1) + } else { + state.opened.splice(currentIndex + 1) + state.opened.splice(1, currentIndex - 1) + } + state.current = pageAim + if (vm && vm.$route.name !== pageAim) { + vm.$router.push({ + name: pageAim + }) + } + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + }, + /** + * @class opened + * @description 关闭所有 tag + * @param {Object} state vuex state + * @param {Object} vm vue + */ + closeAll (state, vm) { + state.opened.splice(1) + // 更新设置到数据库 + this.commit('d2admin/utilVuex2DbByUuid', 'opened') + // 关闭所有的标签页后需要判断一次现在是不是在首页 + if (vm.$route.name !== 'index') { + vm.$router.push({ + name: 'index' + }) + } + }, + /** + * @class pool + * @description 保存 pool (候选池) + * @param {Object} state vuex state + * @param {Array} pool pages + */ + poolSet (state, pool) { + state.pool = pool + } + } +}