diff --git a/vue/src/asset/style/index.scss b/vue/src/asset/style/index.scss index 0523620..bfb04f5 100644 --- a/vue/src/asset/style/index.scss +++ b/vue/src/asset/style/index.scss @@ -45,22 +45,20 @@ a:hover { //非移动端的滚动条样式修改 @include pc { - .scroll-container { - &::-webkit-scrollbar { - width: 6px; + ::-webkit-scrollbar { + width: 6px; - &:horizontal { - height: 6px; - } + &:horizontal { + height: 6px; + } - &-thumb { - width: 6px; - border-radius: 5px; - background-color: rgba($--color-primary, 0.8); + &-thumb { + width: 6px; + border-radius: 5px; + background-color: rgba($--color-primary, 0.8); - &:hover { - background-color: rgba($--color-primary, 1); - } + &:hover { + background-color: rgba($--color-primary, 1); } } } diff --git a/vue/src/component/Empty/index.vue b/vue/src/component/Empty/index.vue index 60d0ddd..6da639f 100644 --- a/vue/src/component/Empty/index.vue +++ b/vue/src/component/Empty/index.vue @@ -1,4 +1,7 @@ @@ -20,5 +16,6 @@ export default { .checkbox-group { display: flex; justify-content: space-around; + width: 100%; } diff --git a/vue/src/component/AbstractForm/FormAnchor.vue b/vue/src/component/form/Anchor/index.vue similarity index 100% rename from vue/src/component/AbstractForm/FormAnchor.vue rename to vue/src/component/form/Anchor/index.vue diff --git a/vue/src/component/AbstractForm/FormCard.vue b/vue/src/component/form/CollapseCard/index.vue similarity index 84% rename from vue/src/component/AbstractForm/FormCard.vue rename to vue/src/component/form/CollapseCard/index.vue index 327c452..c666b85 100644 --- a/vue/src/component/AbstractForm/FormCard.vue +++ b/vue/src/component/form/CollapseCard/index.vue @@ -2,7 +2,7 @@
{{ header }} - +
@@ -10,7 +10,7 @@ diff --git a/vue/src/layout/component/Header/component/Navbar/index.vue b/vue/src/layout/component/Header/component/Navbar/index.vue index 1c9c3f9..7f249a8 100644 --- a/vue/src/layout/component/Header/component/Navbar/index.vue +++ b/vue/src/layout/component/Header/component/Navbar/index.vue @@ -5,8 +5,8 @@ import Bell from "./component/Bell" import Hamburger from './component/Hamburger' import HeadMenu from "./component/HeadMenu" import SettingDrawer from './component/SettingDrawer' -import {getters as mainGetters} from "@/layout/store/main" -import {getters as settingGetters, mutations as settingMutations} from "@/layout/store/setting" +import {getters as appGetters} from "@/layout/store/app" +import {getters as asideGetters, mutations as asideMutations} from "@/layout/store/aside" import {getSidebarMenus} from "@/layout/util" import {elConfirm} from "@/util/message" @@ -22,10 +22,6 @@ export default { computed: mapState('user', ['avatar', 'name', 'prepareLogout']), methods: { - sidebarCtrl() { - settingMutations.sidebarCollapse(!settingGetters.sidebarCollapse) - }, - refresh() { this.$router.replace({path: `/redirect${this.$route.fullPath}`}) }, @@ -52,18 +48,18 @@ export default { //③桌面端且非顶部导航 //④桌面端且未设置侧边栏自动隐藏 const hasSidebarMenus = getSidebarMenus().length > 0, - isMobile = mainGetters.device === 'mobile', - notHeadMode = settingGetters.navMode !== 'head', - notAutoHidden = !settingGetters.sidebarAutoHidden, + isMobile = appGetters.device === 'mobile', + notHeadMode = appGetters.navMode !== 'head', + notAutoHidden = !asideGetters.autoHide, renderHamburger = hasSidebarMenus && (isMobile || notHeadMode && notAutoHidden) if (renderHamburger) { - const active = !settingGetters.sidebarCollapse - return + const active = isMobile ? asideGetters.show : !asideGetters.collapse + return asideMutations.switch()}/> } }, renderHeadMenuMenu() { - if (settingGetters.navMode !== 'aside' && mainGetters.device !== 'mobile') { + if (appGetters.navMode !== 'aside' && appGetters.device !== 'mobile') { return } }, diff --git a/vue/src/layout/component/Header/component/Navbar/style.scss b/vue/src/layout/component/Header/component/Navbar/style.scss index 42783f8..35c77ee 100644 --- a/vue/src/layout/component/Header/component/Navbar/style.scss +++ b/vue/src/layout/component/Header/component/Navbar/style.scss @@ -74,6 +74,11 @@ max-width: 100px; } } + + //submenu的右侧箭头会稍微偏上,不懂为啥 + .el-submenu__icon-arrow { + margin-top: -4px; + } } //顶部菜单的顶级节点 diff --git a/vue/src/layout/component/Header/component/TagsView/index.vue b/vue/src/layout/component/Header/component/TagsView/index.vue index 8e45ca9..024a361 100644 --- a/vue/src/layout/component/Header/component/TagsView/index.vue +++ b/vue/src/layout/component/Header/component/TagsView/index.vue @@ -2,16 +2,15 @@ import shortcutMixin from '@/layout/mixin/shortcut' import decideRouterTransitionMixin from '@/layout/mixin/decideRouterTransition' import {route as routeConfig} from '@/config' -import {getters as mainGetters} from "@/layout/store/main" +import {getters as appGetters} from "@/layout/store/app" import {getters as tagsViewGetters, mutations as tagsViewMutations} from "@/layout/store/tagsView" -import Contextmenu from "@/component/menu/Contextmenu" -import ContextmenuItem from "@/component/menu/ContextmenuItem" +import ContextMenu from "@/component/menu/ContextMenu" import ScrollPane from './ScrollPane' export default { mixins: [shortcutMixin, decideRouterTransitionMixin], - components: {Contextmenu, ContextmenuItem, ScrollPane}, + components: {ContextMenu, ScrollPane}, data() { return { @@ -28,7 +27,7 @@ export default { computed: { visitedViews: () => tagsViewGetters.visitedViews, - menus: () => mainGetters.menus + menus: () => appGetters.menus }, watch: { @@ -166,19 +165,21 @@ export default { ) }) }, - renderContextmenu(h) { + renderContextMenu(h) { const menu = this.contextmenu - return ( - - 刷新 - {!this.isAffix(this.selectedTag) && - this.closeSelectedTag(this.selectedTag)}> - 关闭 - } - 关闭其他 - 关闭全部 - - ) + const items = [ + {content: '刷新', click: this.refreshSelectedTag}, + this.isAffix(this.selectedTag) + ? undefined + : { + content: '关闭', + click: () => this.closeSelectedTag(this.selectedTag) + }, + {content: '关闭其他', click: this.closeOthersTags}, + {content: '关闭全部', click: this.closeAllTags} + ] + + return } }, @@ -198,7 +199,7 @@ export default { {this.renderTags(h)} - {this.renderContextmenu(h)} + {this.renderContextMenu(h)} ) } diff --git a/vue/src/layout/component/Header/index.vue b/vue/src/layout/component/Header/index.vue index e60c76a..ccdb126 100644 --- a/vue/src/layout/component/Header/index.vue +++ b/vue/src/layout/component/Header/index.vue @@ -1,6 +1,5 @@ - - diff --git a/vue/src/layout/component/Main/component/BackToTop.vue b/vue/src/layout/component/Page/component/BackToTop.vue similarity index 93% rename from vue/src/layout/component/Main/component/BackToTop.vue rename to vue/src/layout/component/Page/component/BackToTop.vue index 1ed0004..14aaf37 100644 --- a/vue/src/layout/component/Main/component/BackToTop.vue +++ b/vue/src/layout/component/Page/component/BackToTop.vue @@ -1,7 +1,5 @@ + + diff --git a/vue/src/layout/component/Main/style.scss b/vue/src/layout/component/Page/style.scss similarity index 100% rename from vue/src/layout/component/Main/style.scss rename to vue/src/layout/component/Page/style.scss diff --git a/vue/src/layout/index.vue b/vue/src/layout/index.vue index 142a2fd..edf5df6 100644 --- a/vue/src/layout/index.vue +++ b/vue/src/layout/index.vue @@ -2,23 +2,23 @@ import offlineMixin from './mixin/offline' import VAside from './component/Aside' import VHeader from './component/Header' -import VMain from './component/Main' -import {getters as mainGetters, mutations as mainMutations} from "@/layout/store/main" -import {getters as settingGetters} from "@/layout/store/setting" -import {isMobile} from "@/util/browser" +import VPage from './component/Page' +import {getters as appGetters, mutations as appMutations} from "@/layout/store/app" +import {getters as tagsViewGetters} from "@/layout/store/tagsView" import {debounce} from "@/util" +import {isMobile} from "@/util/browser" export default { name: 'Layout', mixins: [offlineMixin], - components: {VAside, VHeader, VMain}, + components: {VAside, VHeader, VPage}, computed: { containerClass() { - const arr = ['main-container', 'has-nav', `nav-mode-${settingGetters.navMode}`] - settingGetters.useTagsView && arr.push('has-tags-view') + const arr = ['main-container', 'has-nav', `nav-mode-${appGetters.navMode}`] + tagsViewGetters.enabled && arr.push('has-tags-view') return arr } }, @@ -27,7 +27,7 @@ export default { $_resizeHandler() { if (!document.hidden) { const mobile = isMobile() - mainMutations.device(mobile ? 'mobile' : 'pc') + appMutations.device(mobile ? 'mobile' : 'pc') } } }, @@ -44,14 +44,14 @@ export default { }, render() { - const renderAide = mainGetters.device === 'mobile' || settingGetters.navMode !== 'head' + const renderAide = appGetters.device === 'mobile' || appGetters.navMode !== 'head' return (
{renderAide && }
- +
) diff --git a/vue/src/layout/store/main.js b/vue/src/layout/store/app.js similarity index 89% rename from vue/src/layout/store/main.js rename to vue/src/layout/store/app.js index e2833e3..1fa7839 100644 --- a/vue/src/layout/store/main.js +++ b/vue/src/layout/store/app.js @@ -11,13 +11,33 @@ const state = { activeRootMenu: '', //所有的树形菜单,每个元素为顶部菜单,顶部菜单的子级(如果有)为侧边栏菜单 - menus: [] + menus: [], + + //主题色 + color: '#1890ff', + //导航模式 + navMode: 'mix' } const store = Vue.observable(state) +export const getters = createGetters(store) + +export const mutations = { + ...createMutations(store), + + menus(v) { + sort(v) + store.menus = v + } +} + //菜单排序 function sort(routes) { + if (!Array.isArray(routes) || routes.length === 0) { + return + } + const getSortValue = item => { const sort = deepTap(item) return isEmpty(sort) ? 10000 : sort @@ -47,14 +67,3 @@ function sort(routes) { } }) } - -export const getters = createGetters(store) - -export const mutations = { - ...createMutations(store), - - menus(v) { - sort(v) - store.menus = v - } -} diff --git a/vue/src/layout/store/aside.js b/vue/src/layout/store/aside.js new file mode 100644 index 0000000..3c7587d --- /dev/null +++ b/vue/src/layout/store/aside.js @@ -0,0 +1,75 @@ +/** + * 侧边栏的响应式数据 + */ +import Vue from 'vue' +import {bindThis} from "@/util" +import {createGetters, createMutations} from "@/util/observable" +import {getters as appGetters} from "./app" + +const state = { + //抽屉模式时的显隐 + show: false, + + //显示顶部logo + showLogo: true, + + //手风琴效果 + uniqueOpen: true, + + //是否折叠 + collapse: false, + + //折叠时显示上级 + showParentOnCollapse: false, + + //自动隐藏 + autoHide: false +} + +const store = Vue.observable(state) + +export const getters = createGetters(store) + +export const mutations = bindThis({ + ...createMutations(store), + + /*折叠和自动隐藏不能同时启用*/ + collapse(v) { + if (v) store.autoHide = false + store.collapse = v + }, + autoHide(v) { + if (v) store.collapse = false + store.autoHide = v + }, + + /*移动端是打开关闭抽屉,桌面端是展开折叠*/ + open() { + if (appGetters.device === 'mobile') { + store.show = true + } + else store.collapse = false + }, + close() { + if (appGetters.device === 'mobile') { + store.show = false + } + else store.collapse = true + }, + //切换侧边栏的状态 + switch(action) { + switch (action) { + case 'open': + return this.open() + case 'close': + return this.close() + default : + let open = true + if (appGetters.device === 'mobile') { + open = !store.show + } + else open = store.collapse + return open ? this.open() : this.close() + } + } +}) diff --git a/vue/src/layout/store/iframe.js b/vue/src/layout/store/iframe.js deleted file mode 100644 index 0a835e2..0000000 --- a/vue/src/layout/store/iframe.js +++ /dev/null @@ -1,35 +0,0 @@ -import Vue from 'vue' -import {createGetters} from "@/util/observable" - -const state = { - show: false, - current: '', - list: [] -} - -const store = Vue.observable(state) - -function add(src) { - !store.list.includes(src) && store.list.push(src) -} - -function del(src) { - const index = store.list.findIndex(i => i === src) - index > -1 && store.list.splice(index, 1) -} - -function open({src}) { - store.show = true - store.current = src - add(src) -} - -function close({src, del: needDelete}) { - store.show = false - store.current = '' - needDelete && del(src) -} - -export const getters = createGetters(store) - -export const mutations = {del, open, close} diff --git a/vue/src/layout/store/page.js b/vue/src/layout/store/page.js new file mode 100644 index 0000000..efc85da --- /dev/null +++ b/vue/src/layout/store/page.js @@ -0,0 +1,44 @@ +/** + * 路由页面的响应式数据 + */ +import Vue from 'vue' +import {bindThis} from "@/util" +import {createGetters, createMutations} from "@/util/observable" + +const state = { + /*iframe的控制*/ + showIframe: false, + currentIframe: '', + iframeList: [], + + //是否显示页头 + showPageHeader: true, + //是否显示返回顶部按钮 + showBackToTop: true +} + +const store = Vue.observable(state) + +export const getters = createGetters(store) + +export const mutations = bindThis({ + ...createMutations(store), + + addIframe(src) { + !store.iframeList.includes(src) && store.iframeList.push(src) + }, + delIframe(src) { + const index = store.iframeList.findIndex(i => i === src) + index > -1 && store.iframeList.splice(index, 1) + }, + openIframe({src}) { + store.showIframe = true + store.currentIframe = src + this.addIframe(src) + }, + closeIframe({src, del}) { + store.showIframe = false + store.currentIframe = '' + del && this.delIframe(src) + } +}) diff --git a/vue/src/layout/store/setting.js b/vue/src/layout/store/setting.js deleted file mode 100644 index 1a60b24..0000000 --- a/vue/src/layout/store/setting.js +++ /dev/null @@ -1,69 +0,0 @@ -import Vue from 'vue' -import {isEmpty} from "@/util" -import {createGetters} from "@/util/observable" -import {getLocalPersonalSettings, setLocalPersonalSettings} from "@/util/storage" - -const state = { - //主题色 - themeColor: '#1890ff', - //导航模式 - navMode: 'mix', - - //是否显示logo - showLogo: true, - //是否显示页头 - showPageHeader: true, - //是否使用多页签 - useTagsView: true, - - //侧边栏菜单手风琴效果 - sidebarUniqueOpen: true, - //侧边栏菜单是否折叠 - sidebarCollapse: false, - //侧边栏菜单折叠时,弹出菜单是否显示上级 - sidebarShowParent: false, - //是否自动隐藏侧边栏菜单 - sidebarAutoHidden: false, - - //是否显示返回顶部按钮 - showBackToTop: true, -} - -//state填入初始值 -const localSettings = getLocalPersonalSettings() -Object.keys(state).forEach(key => { - if (!isEmpty(localSettings[key])) state[key] = localSettings[key] -}) - -const store = Vue.observable(state) - -//每次修改个人设置时,同步到localStorage -function createMutations(store) { - return Object.keys(store).reduce((mutations, key) => { - mutations[key] = data => { - store[key] = data - setLocalPersonalSettings(store) - } - return mutations - }, {}) -} - -export const getters = createGetters(store) - -export const mutations = { - ...createMutations(store), - - sidebarCollapse(v) { - //当启用侧边栏折叠时,停用自动隐藏侧边栏 - if (v) store.sidebarAutoHidden = false - store.sidebarCollapse = v - setLocalPersonalSettings(store) - }, - - sidebarAutoHidden(v) { - //当启用自动隐藏侧边栏时,停用侧边栏折叠 - if (v) store.sidebarCollapse = false - store.sidebarAutoHidden = v - setLocalPersonalSettings(store) - } -} diff --git a/vue/src/layout/store/tagsView.js b/vue/src/layout/store/tagsView.js index f7a8ead..9d17f1f 100644 --- a/vue/src/layout/store/tagsView.js +++ b/vue/src/layout/store/tagsView.js @@ -1,9 +1,17 @@ +/** + * 多页签的响应式数据 + */ import Vue from 'vue' import {route as routeConfig} from "@/config" -import {mutations as iframeMutations} from "@/layout/store/iframe" +import {mutations as pageMutations} from "@/layout/store/page" +import {getRouterViewCacheKey} from "@/layout/util" +import {bindThis} from "@/util" import {createGetters, createMutations} from "@/util/observable" const state = { + //是否启用 + enabled: true, + //显示的页签,{...route,title:route.meta.title}对象数组 visitedViews: [], @@ -16,70 +24,63 @@ const state = { const store = Vue.observable(state) -function getCachedViewKey(view) { - const {usePathKey, useFullPathKey} = view.meta || {} - return usePathKey ? view.path : useFullPathKey ? view.fullPath : view.name -} - -function addVisitedView(view) { - const {title = '暂无标题'} = view.meta || {} - - if (store.visitedViews.some(v => v.path === view.path)) return - - store.visitedViews.push({...view, title}) -} - -function addCachedView(view) { - const {noCache, iframe, usePathKey, useFullPathKey} = view.meta || {} +export const getters = createGetters(store) - if (noCache || iframe || !view.name && !usePathKey && !useFullPathKey) return +export const mutations = bindThis({ + ...createMutations(store), - const key = getCachedViewKey(view) + enabled(v) { + store.enabled = v + //多页签停用时清除所有页面缓存 + !v && this.delAllViews() + }, - if (store.cachedViews.includes(key)) return + addVisitedView(view) { + const {title = '暂无标题'} = view.meta || {} - store.cachedViews.push(key) -} + if (store.visitedViews.some(v => v.path === view.path)) return -function delVisitedView(view) { - const index = store.visitedViews.findIndex(i => i.path === view.path) - index > -1 && store.visitedViews.splice(index, 1) -} + store.visitedViews.push({...view, title}) + }, + addCachedView(view) { + const {noCache, iframe, usePathKey, useFullPathKey} = view.meta || {} -function delCachedView(view) { - const key = getCachedViewKey(view) - const index = store.cachedViews.indexOf(key) - index > -1 && store.cachedViews.splice(index, 1) -} + if (noCache || iframe || !view.name && !usePathKey && !useFullPathKey) return -export const getters = createGetters(store) + const key = getRouterViewCacheKey(view) -export const mutations = { - ...createMutations(store), + if (store.cachedViews.includes(key)) return - addVisitedView, - addCachedView, + store.cachedViews.push(key) + }, addView(view) { - addVisitedView(view) - addCachedView(view) + this.addVisitedView(view) + this.addCachedView(view) }, - delVisitedView, - delCachedView, + delVisitedView(view) { + const index = store.visitedViews.findIndex(i => i.path === view.path) + index > -1 && store.visitedViews.splice(index, 1) + }, + delCachedView(view) { + const key = getRouterViewCacheKey(view) + const index = store.cachedViews.indexOf(key) + index > -1 && store.cachedViews.splice(index, 1) + }, delView(view) { - delVisitedView(view) - delCachedView(view) - iframeMutations.del(view.meta ? view.meta.iframe : null) + this.delVisitedView(view) + this.delCachedView(view) + pageMutations.delIframe(view.meta ? view.meta.iframe : null) }, delOthersViews(view) { const visitedViews = store.visitedViews.filter(v => v.meta.affix || v.path === view.path) - const name = store.cachedViews.find(name => name === getCachedViewKey(view)) + const key = store.cachedViews.find(key => key === getRouterViewCacheKey(view)) store.visitedViews = visitedViews - store.cachedViews = name ? [name] : [] + store.cachedViews = key ? [key] : [] }, delAllViews() { store.visitedViews = store.visitedViews.filter(tag => tag.meta && tag.meta.affix) store.cachedViews = [] } -} +}) diff --git a/vue/src/layout/util.js b/vue/src/layout/util.js index c63a0eb..905885f 100644 --- a/vue/src/layout/util.js +++ b/vue/src/layout/util.js @@ -1,22 +1,27 @@ -import {getters as mainGetters} from "@/layout/store/main" -import {getters as settingGetters} from "@/layout/store/setting" +import {getters as appGetters} from "@/layout/store/app" + +//获取路由页面缓存所需的key +export function getRouterViewCacheKey({name, path, fullPath, meta = {}}) { + const {usePathKey, useFullPathKey} = meta + return usePathKey ? path : useFullPathKey ? fullPath : name +} //获取侧边栏的菜单 export function getSidebarMenus() { - const menus = mainGetters.menus + const menus = appGetters.menus if (!Array.isArray(menus)) { return [] } - if (mainGetters.device === 'mobile') { + if (appGetters.device === 'mobile') { return menus } - switch (settingGetters.navMode) { + switch (appGetters.navMode) { case 'aside': return menus case 'head': return [] case 'mix': - const root = menus.find(i => i.path === mainGetters.activeRootMenu) + const root = menus.find(i => i.path === appGetters.activeRootMenu) return root ? root.children || [] : [] } } diff --git a/vue/src/mixin/docDetailMixin.js b/vue/src/mixin/docDetailMixin.js index fe00a66..d4298f3 100644 --- a/vue/src/mixin/docDetailMixin.js +++ b/vue/src/mixin/docDetailMixin.js @@ -1,11 +1,11 @@ import {commonMethods} from "@/mixin/docTableMixin" -import AbstractForm from '@/component/AbstractForm' -import AbstractFormItem from "@/component/AbstractForm/item" -import AbstractTable from "@/component/AbstractTable" +import AbstractForm from '@/component/abstract/Form' +import AbstractFormItem from "@/component/abstract/Form/item" +import AbstractTable from "@/component/abstract/Table" import DetailPage from "@/view/app/common/DetailPage" import DocHistory from '@/component/biz/doc/DocHistory' import DocSteps from '@/component/biz/doc/DocSteps' -import FormCard from '@/component/AbstractForm/FormCard' +import FormCollapseCard from '@/component/form/CollapseCard' import UploadFile from '@/component/UploadFile' import {isEmpty, mergeObj} from '@/util' import {auth} from "@/util/auth" @@ -21,7 +21,7 @@ export default { DetailPage, DocHistory, DocSteps, - FormCard, + FormCollapseCard, UploadFile }, diff --git a/vue/src/mixin/guide/data/navbar.js b/vue/src/mixin/guide/data/navbar.js index 05989b4..29d6123 100644 --- a/vue/src/mixin/guide/data/navbar.js +++ b/vue/src/mixin/guide/data/navbar.js @@ -8,7 +8,7 @@ const steps = [ content: '这是个性设置按钮,可以根据自己喜好进行一些设置', }, { - element: '.avatar-container.navbar-item', + element: '.navbar .el-dropdown.navbar-item', content: '这是用户中心', }, { diff --git a/vue/src/mixin/tablePageMixin.js b/vue/src/mixin/tablePageMixin.js index d7fd4b4..3a09738 100644 --- a/vue/src/mixin/tablePageMixin.js +++ b/vue/src/mixin/tablePageMixin.js @@ -2,8 +2,8 @@ * 列表页通用混入 * 引用者必须要有search方法 * */ -import AbstractPagination from '@/component/AbstractPagination' -import AbstractTable from '@/component/AbstractTable' +import AbstractPagination from '@/component/abstract/Pagination' +import AbstractTable from '@/component/abstract/Table' const mixin = { components: {AbstractPagination, AbstractTable}, diff --git a/vue/src/router/guard/iframe.js b/vue/src/router/guard/iframe.js index 3778a18..0bacebd 100644 --- a/vue/src/router/guard/iframe.js +++ b/vue/src/router/guard/iframe.js @@ -1,19 +1,17 @@ -import {mutations as iframeMutations} from "@/layout/store/iframe" +import {mutations as pageMutations} from "@/layout/store/page" const beforeEach = (to, from, next) => { //从iframe页面离开时,判断是否需要删除iframe if (from.meta.iframe) { - let del = false //如果设置了无缓存或是进行了刷新,那么移除iframe - if (from.meta.noCache || to.path === `/redirect${from.path}`) { - del = true - } - iframeMutations.close({src: from.meta.iframe, del}) + const del = from.meta.noCache || to.path === `/redirect${from.path}` + + pageMutations.closeIframe({src: from.meta.iframe, del}) } //跳转至iframe页面时,打开iframe if (to.meta.iframe) { - iframeMutations.open({src: to.meta.iframe}) + pageMutations.openIframe({src: to.meta.iframe}) } next() diff --git a/vue/src/store/module/app.js b/vue/src/store/module/app.js index 634c17d..dc9ec83 100644 --- a/vue/src/store/module/app.js +++ b/vue/src/store/module/app.js @@ -1,4 +1,4 @@ -import {createMutations} from "@/util" +import {createMutations} from "@/store/util" const state = { //登陆页背景动画 diff --git a/vue/src/store/module/message.js b/vue/src/store/module/message.js index 8d478a1..03f4a1b 100644 --- a/vue/src/store/module/message.js +++ b/vue/src/store/module/message.js @@ -1,4 +1,4 @@ -import {createMutations} from "@/util" +import {createMutations} from "@/store/util" import {search} from '@/api/message/user' const state = { diff --git a/vue/src/store/module/resource.js b/vue/src/store/module/resource.js index 13716db..a2c252c 100644 --- a/vue/src/store/module/resource.js +++ b/vue/src/store/module/resource.js @@ -1,6 +1,6 @@ import path from 'path' import {route as routeConfig} from '@/config' -import {mutations as mainMutations} from "@/layout/store/main" +import {mutations as appMutations} from "@/layout/store/app" import {addDynamicRoutes} from '@/router' import {getDynamicRoutes} from '@/router/define' import {parseRoutes, metaExtend} from "@/router/util" @@ -61,7 +61,7 @@ const actions = { //获取经过权限过滤后的菜单 const menus = getAuthorizedMenus({resources, admin}, routes) - mainMutations.menus(menus) + appMutations.menus(menus) commit('resource', {data: data || [], admin}) //设置初始化完成的标志 diff --git a/vue/src/store/module/socket.js b/vue/src/store/module/socket.js index 4a9f81b..03939d4 100644 --- a/vue/src/store/module/socket.js +++ b/vue/src/store/module/socket.js @@ -2,7 +2,7 @@ import {MessageBox} from "element-ui" import {isEmpty} from "@/util" import {useMock, socketUrl} from '@/config' import SocketIO from 'socket.io-client' -import {createMutations} from "@/util" +import {createMutations} from "@/store/util" let socket diff --git a/vue/src/store/module/user.js b/vue/src/store/module/user.js index b36a615..044a02a 100644 --- a/vue/src/store/module/user.js +++ b/vue/src/store/module/user.js @@ -1,4 +1,5 @@ -import {createMutations, emptyOrDefault} from "@/util" +import {createMutations} from "@/store/util" +import {emptyOrDefault} from "@/util" import {autoCompleteUrl} from "@/util/file" import {getUser, setUser} from "@/util/storage" import {mutations as tagsViewMutations} from "@/layout/store/tagsView" diff --git a/vue/src/store/util.js b/vue/src/store/util.js new file mode 100644 index 0000000..72267f5 --- /dev/null +++ b/vue/src/store/util.js @@ -0,0 +1,18 @@ +import {getInitialValue} from "@/util" + +//vuex中根据state批量生成对应的mutation +export function createMutations(state, all = false) { + const keys = Object.keys(state) + const obj = {} + keys.forEach(key => { + obj[key] = (s, v) => s[key] = v + }) + if (all) { + obj['$all'] = (s, v) => { + keys.forEach(key => { + s[key] = v && v[key] || getInitialValue(s[key]) + }) + } + } + return obj +} diff --git a/vue/src/util/index.js b/vue/src/util/index.js index 6bcb108..9c704a0 100644 --- a/vue/src/util/index.js +++ b/vue/src/util/index.js @@ -177,23 +177,6 @@ export function waitUntilSuccess(success, callback, interval = 1000, maxTryTime }) } -//vuex中根据state批量生成对应的mutation -export function createMutations(state, all = false) { - const keys = Object.keys(state) - const obj = {} - keys.forEach(key => { - obj[key] = (s, v) => s[key] = v - }) - if (all) { - obj['$all'] = (s, v) => { - keys.forEach(key => { - s[key] = v && v[key] || getInitialValue(s[key]) - }) - } - } - return obj -} - //删除所有url参数 export function delAllUrlParam() { let paramStartIndex = location.href.indexOf('?') @@ -202,3 +185,17 @@ export function delAllUrlParam() { history.replaceState(null, null, [...href].join('')) } } + +//将传入对象的所有函数的this绑定为其自身 +export function bindThis(obj, root = obj) { + if (!obj || typeof obj !== 'object') return + + Object.entries(obj).forEach(([k, v]) => { + if (typeof v === 'function') { + obj[k] = v.bind(root) + } + bindThis(v, root) + }) + + return obj +} diff --git a/vue/src/util/secret.js b/vue/src/util/secret.js index ec8fe08..ada8f32 100644 --- a/vue/src/util/secret.js +++ b/vue/src/util/secret.js @@ -3,17 +3,17 @@ import pako from 'pako' export function unzip(b64Data) { let strData = atob(b64Data) // Convert binary string to character-number array - let charData = strData.split('').map(x => x.charCodeAt(0)) + const charData = strData.split('').map(x => x.charCodeAt(0)) // Turn number array into byte-array - let binData = new Uint8Array(charData) + const binData = new Uint8Array(charData) // unzip - let data = pako.inflate(binData) + const data = pako.inflate(binData) // Convert gunzipped byteArray back to ascii string: strData = String.fromCharCode.apply(null, new Uint16Array(data)) return decodeURIComponent(strData) } export function zip(str) { - let binaryString = pako.gzip(encodeURIComponent(str), {to: 'string'}) + const binaryString = pako.gzip(encodeURIComponent(str), {to: 'string'}) return btoa(binaryString) } diff --git a/vue/src/util/storage.js b/vue/src/util/storage.js index 6113304..d54b3bb 100644 --- a/vue/src/util/storage.js +++ b/vue/src/util/storage.js @@ -34,7 +34,7 @@ export function getLocalPersonalSettings() { obj = JSON.parse(obj) } catch (e) { - console.error('个性化设置数据异常!', e) + console.error('本地个性化设置数据解析失败!', e) removeLocalPersonalSettings() return {} } diff --git a/vue/src/view/app/common/DetailPage/index.vue b/vue/src/view/app/common/DetailPage/index.vue index 60e4da4..89accf0 100644 --- a/vue/src/view/app/common/DetailPage/index.vue +++ b/vue/src/view/app/common/DetailPage/index.vue @@ -1,6 +1,6 @@ - diff --git a/vue/src/view/message/manage/EditDialog.vue b/vue/src/view/message/manage/EditDialog.vue index 3fe1223..838ca24 100644 --- a/vue/src/view/message/manage/EditDialog.vue +++ b/vue/src/view/message/manage/EditDialog.vue @@ -1,5 +1,5 @@ - +