diff --git a/mock/login.js b/mock/login.js
index 20d1d75..3405e40 100644
--- a/mock/login.js
+++ b/mock/login.js
@@ -23,7 +23,7 @@ export default [
data: {
id: 1,
name: 'zhangsan',
- role: 'visitor',
+ 'role|1': ['admin', 'visitor'], // 随机返回一个角色admin或visitor
avatar: "@image('48x48', '#fb0a2a')"
}
},
diff --git a/src/assets/style/global-variables.scss b/src/assets/style/global-variables.scss
index 7a16833..7c88bb1 100644
--- a/src/assets/style/global-variables.scss
+++ b/src/assets/style/global-variables.scss
@@ -2,7 +2,7 @@
$mainColor: #409eff; // 网站主题色
-// 菜单配置
+// 侧边栏
$menuBg: #304156; // 菜单背景颜色
$menuTextColor: #fff; // 菜单文字颜色
$menuActiveTextColor: $mainColor; // 已选中菜单文字颜色
diff --git a/src/layout/components/Content/index.vue b/src/layout/components/Content/index.vue
index 562b2b4..82b296a 100644
--- a/src/layout/components/Content/index.vue
+++ b/src/layout/components/Content/index.vue
@@ -1,16 +1,9 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
\ No newline at end of file
diff --git a/src/layout/components/Sidebar/Menus.vue b/src/layout/components/Sidebar/Menus.vue
index 10cf648..3d80d78 100644
--- a/src/layout/components/Sidebar/Menus.vue
+++ b/src/layout/components/Sidebar/Menus.vue
@@ -10,13 +10,7 @@
:text-color="variables.menuTextColor"
:active-text-color="variables.menuActiveTextColor"
>
-
-
-
+
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 15d9858..f622f13 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -1,11 +1,12 @@
+
+ border-bottom: 1px solid #eaeaea;
-
diff --git a/src/layout/components/Topbar/Breadcrumbs.vue b/src/layout/components/Topbar/Breadcrumbs.vue
index 4203a7c..7a347ec 100644
--- a/src/layout/components/Topbar/Breadcrumbs.vue
+++ b/src/layout/components/Topbar/Breadcrumbs.vue
@@ -2,23 +2,27 @@
- {{item.meta.title}}
+ {{ item.meta.title }}
\ No newline at end of file
diff --git a/src/layout/hooks/useResizeHandler.js b/src/layout/hooks/useResizeHandler.js
new file mode 100644
index 0000000..c797db6
--- /dev/null
+++ b/src/layout/hooks/useResizeHandler.js
@@ -0,0 +1,46 @@
+import { onBeforeMount, onBeforeUnmount, watch } from "vue"
+import { useRouter } from "vue-router"
+import { useStore } from "vuex"
+
+const WIDTH = 768
+export const useResizeHandler = () => {
+ const store = useStore()
+ const router = useRouter()
+ const route = router.currentRoute
+
+ const isMobile = () => {
+ return window.innerWidth < WIDTH
+ }
+
+ const resizeHandler = () => {
+ if (isMobile()) {
+ store.commit('app/setDevice', 'mobile')
+ store.commit('app/setCollapse', 1)
+ } else {
+ store.commit('app/setDevice', 'desktop')
+ store.commit('app/setCollapse', 0)
+ }
+ }
+
+ onBeforeMount(() => {
+ if (isMobile()) {
+ store.commit('app/setDevice', 'mobile')
+ store.commit('app/setCollapse', 1)
+ }
+ window.addEventListener('resize', resizeHandler)
+ })
+
+ onBeforeUnmount(() => {
+ window.removeEventListener('resize', resizeHandler)
+ })
+
+ // // 监听路由的时候不能使用useRoute获取路由,否则会有警告
+ // watch(route, () => {
+ // if (store.state.app.device === 'mobile' && !store.state.app.sidebar.collapse) {
+ // store.commit('app/setCollapse', 1)
+ // }
+ // })
+
+}
+
+
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 0389394..fa99834 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -6,7 +6,9 @@
-
+
+
+
@@ -16,14 +18,19 @@ import Sidebar from "./components/Sidebar/index.vue";
import Topbar from "./components/Topbar/index.vue";
import Tagsbar from "./components/Tagsbar/index.vue";
import Content from "./components/Content/index.vue";
+import { useResizeHandler } from "./hooks/useResizeHandler";
export default defineComponent({
+ name: "layout",
components: {
Sidebar,
Topbar,
Tagsbar,
Content,
},
+ setup() {
+ useResizeHandler();
+ },
});
@@ -34,11 +41,18 @@ export default defineComponent({
.right {
flex: 1;
+ overflow: hidden;
display: flex;
flex-direction: column;
.top {
background: #fff;
}
+ .main {
+ flex: 1;
+ background: #f0f2f5;
+ padding: 16px;
+ overflow: auto;
+ }
}
}
\ No newline at end of file
diff --git a/src/router/index.js b/src/router/index.js
index bd376f3..14c29e9 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,6 +1,7 @@
// index.js
import { createRouter, createWebHashHistory } from "vue-router"
+import redirect from './modules/redirect'
import error from './modules/error'
import login from './modules/login'
import home from './modules/home'
@@ -20,10 +21,18 @@ const router = createRouter({
path: '/',
redirect: '/home',
},
+ ...redirect, // 统一的重定向配置
...login,
...allMenus,
...error
],
+ scrollBehavior (to, from, savedPosition) {
+ if (savedPosition) {
+ return savedPosition
+ } else {
+ return { left: 0, top: 0 }
+ }
+ },
});
export default router;
\ No newline at end of file
diff --git a/src/router/modules/error.js b/src/router/modules/error.js
index 70f11fb..0238cd6 100644
--- a/src/router/modules/error.js
+++ b/src/router/modules/error.js
@@ -1,16 +1,17 @@
-import layout from '@/layout/index.vue'
+const Layout = () => import('@/layout/index.vue')
const Error = () => import("@/views/error/index.vue");
export default [
{
path: '/error',
- component: layout,
+ component: Layout,
children: [
{
path: '403',
name: 'error-forbidden',
component: Error,
+ meta: { title: '403' },
props: {
error: '403'
}
@@ -19,6 +20,7 @@ export default [
path: '500',
name: 'error-server-error',
component: Error,
+ meta: { title: '500' },
props: {
error: '500'
}
@@ -27,6 +29,7 @@ export default [
path: '404',
name: 'error-not-found',
component: Error,
+ meta: { title: '404' },
props: {
error: '404'
}
diff --git a/src/router/modules/home.js b/src/router/modules/home.js
index 4271c55..866773e 100644
--- a/src/router/modules/home.js
+++ b/src/router/modules/home.js
@@ -1,11 +1,11 @@
// home.js
-import layout from '@/layout/index.vue'
+const Layout = () => import('@/layout/index.vue')
const Home = () => import("@/views/home/index.vue");
export default [
{
path: '/home',
- component: layout,
+ component: Layout,
name: "Dashboard",
meta: {
title: "Dashboard",
@@ -18,6 +18,7 @@ export default [
component: Home,
meta: {
title: "首页",
+ affix: true
}
}
]
diff --git a/src/router/modules/redirect.js b/src/router/modules/redirect.js
new file mode 100644
index 0000000..08d5792
--- /dev/null
+++ b/src/router/modules/redirect.js
@@ -0,0 +1,8 @@
+const Redirect = () => import("@/views/redirect/index.vue");
+
+export default [
+ {
+ path: '/redirect/:path(.*)',
+ component: Redirect,
+ }
+]
\ No newline at end of file
diff --git a/src/router/modules/test.js b/src/router/modules/test.js
index 1e3d35c..b1bae09 100644
--- a/src/router/modules/test.js
+++ b/src/router/modules/test.js
@@ -1,15 +1,18 @@
-import layout from '@/layout/index.vue'
+const Layout = () => import('@/layout/index.vue')
const List = () => import("@/views/test/index.vue");
const Add = () => import("@/views/test/Add.vue");
const Auth = () => import("@/views/test/Auth.vue");
+const NoAuth = () => import("@/views/test/NoAuth.vue");
const Nest = () => import("@/views/test/Nest.vue");
const NestPage1 = () => import("@/views/test/nest/Page1.vue");
const NestPage2 = () => import("@/views/test/nest/Page2.vue");
+const Iscache = () => import("@/views/test/Cache.vue");
+const Nocache = () => import("@/views/test/Nocache.vue");
export default [
{
path: '/test',
- component: layout,
+ component: Layout,
name: "test",
meta: {
title: "测试页面",
@@ -40,9 +43,38 @@ export default [
path: "auth",
name: "testAuth",
component: Auth,
+ meta: {
+ title: "权限测试",
+ roles: ["admin", "visitor"],
+ }
+ },
+ {
+ path: "noauth",
+ name: "testNoAuth",
+ component: NoAuth,
meta: {
title: "权限页面",
roles: ["admin"],
+ },
+ hidden: true
+ },
+ {
+ path: "cache",
+ name: "test-cache",
+ component: Iscache,
+ meta: {
+ title: "该页面可缓存",
+ roles: ["admin", "visitor"]
+ }
+ },
+ {
+ path: "nocache",
+ name: "test-no-cache",
+ component: Nocache,
+ meta: {
+ title: "该页面不缓存",
+ roles: ["admin", "visitor"],
+ noCache: true, // 不缓存页面
}
},
{
diff --git a/src/store/modules/app.js b/src/store/modules/app.js
index 8dea054..58e791b 100644
--- a/src/store/modules/app.js
+++ b/src/store/modules/app.js
@@ -1,5 +1,6 @@
import { getItem, setItem, removeItem } from "@/utils/storage"; //getItem和setItem是封装的操作localStorage的方法
-export const TOKEN = "TOKEN";
+export const TOKEN = "VEA-TOKEN";
+const COLLAPSE = "VEA-COLLAPSE";
export default {
namespaced: true,
@@ -7,8 +8,9 @@ export default {
title: 'Vue3 Element Admin',
authorization: getItem(TOKEN),
sidebar: {
- collapse: getItem('collapse')
- }
+ collapse: getItem(COLLAPSE)
+ },
+ device: 'desktop',
},
mutations: {
setToken (state, data) {
@@ -18,19 +20,22 @@ export default {
},
clearToken (state) {
state.authorization = '';
- // 保存到localStorage
+
removeItem(TOKEN);
},
setCollapse (state, data) {
state.sidebar.collapse = data;
// 保存到localStorage
- setItem('collapse', data);
+ setItem(COLLAPSE, data);
},
clearCollapse (state) {
state.sidebar.collapse = '';
- // 保存到localStorage
- removeItem('collapse');
- }
+
+ removeItem(COLLAPSE);
+ },
+ setDevice (state, device) {
+ state.device = device
+ },
},
actions: {},
};
\ No newline at end of file
diff --git a/src/store/modules/tags.js b/src/store/modules/tags.js
index 413e6c1..6d26b2a 100644
--- a/src/store/modules/tags.js
+++ b/src/store/modules/tags.js
@@ -1,20 +1,28 @@
+import { getItem, setItem, removeItem } from "@/utils/storage"; //getItem和setItem是封装的操作localStorage的方法
+
+const TAGLIST = 'VEA-TAGLIST'
+
const state = {
- tagList: [],
+ tagList: getItem(TAGLIST) || [],
cacheList: [],
activePosition: 0
}
const mutations = {
- ADD_TAG_LIST: (state, tag) => {
- if (state.tagList.some(v => v.path === tag.path)) return;
+ ADD_TAG_LIST: (state, { path, fullPath, name, meta }) => {
+ if (state.tagList.some(v => v.path === path)) return false;
+
state.tagList.splice(
state.activePosition + 1,
0,
- Object.assign({}, tag, {
- title: tag.meta.title || 'no-name'
+ Object.assign({}, { path, fullPath, name, meta }, {
+ title: meta.title || '未命名',
+ fullPath: fullPath || path
})
)
+ // 保存到localStorage
+ setItem(TAGLIST, state.tagList);
},
ADD_CACHE_LIST: (state, tag) => {
if (state.cacheList.includes(tag.name)) return
@@ -25,6 +33,8 @@ const mutations = {
DEL_TAG_LIST: (state, tag) => {
state.tagList = state.tagList.filter(v => v.path !== tag.path)
+ // 保存到localStorage
+ setItem(TAGLIST, state.tagList);
},
DEL_CACHE_LIST: (state, tag) => {
state.cacheList = state.cacheList.filter(v => v !== tag.name)
@@ -32,6 +42,8 @@ const mutations = {
DEL_OTHER_TAG_LIST: (state, tag) => {
state.tagList = state.tagList.filter(v => !!v.meta.affix || v.path === tag.path)
+ // 保存到localStorage
+ setItem(TAGLIST, state.tagList);
},
DEL_OTHER_CACHE_LIST: (state, tag) => {
state.cacheList = state.cacheList.filter(v => v === tag.name)
@@ -39,6 +51,8 @@ const mutations = {
DEL_ALL_TAG_LIST: state => {
state.tagList = state.tagList.filter(v => !!v.meta.affix)
+ // 保存到localStorage
+ removeItem(TAGLIST);
},
DEL_ALL_CACHE_LIST: state => {
state.cacheList = []
@@ -47,7 +61,9 @@ const mutations = {
UPDATE_TAG_LIST: (state, tag) => {
const index = state.tagList.findIndex(v => v.path === tag.path);
if (index > -1) {
- state.tagList[index] = Object.assign({}, tag)
+ state.tagList[index] = Object.assign({}, state.tagList[index], tag)
+ // 保存到localStorage
+ setItem(TAGLIST, state.tagList);
}
},
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index cf5f445..c5c71ac 100644
--- a/src/views/home/index.vue
+++ b/src/views/home/index.vue
@@ -1,6 +1,16 @@
home
+
+
+