From 0091a5fab232e313460ecbdc9acf596871100211 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9C=89=E6=9D=A5=E6=8A=80=E6=9C=AF?= <1490493387@qq.com>
Date: Sat, 20 Nov 2021 23:59:45 +0800
Subject: [PATCH] .
---
README.md | 4 +-
package.json | 1 +
src/components/Breadcrumb/index.vue | 103 +++++++++++++
src/components/Hamburger/index.vue | 44 ++++++
src/components/HelloWorld.vue | 27 ----
src/components/SvgIcon/index.vue | 62 ++++++++
src/layout/components/AppMain.vue | 40 +++++
src/layout/components/Navbar.vue | 139 ++++++++++++++++++
src/layout/components/Sidebar/Link.vue | 43 ++++++
src/layout/components/Sidebar/Logo.vue | 82 +++++++++++
src/layout/components/Sidebar/SidebarItem.vue | 103 +++++++++++++
src/layout/components/Sidebar/index.vue | 56 +++++++
src/layout/components/index.ts | 3 +
src/layout/index.vue | 120 +++++++++------
src/layout/mixin/ResizeHandler.ts | 63 ++++++++
src/store/index.ts | 31 ++--
src/store/interface.ts | 11 +-
src/store/modules/app.ts | 47 ++++++
src/store/modules/user.ts | 10 +-
src/utils/validate.ts | 12 ++
20 files changed, 908 insertions(+), 93 deletions(-)
create mode 100644 src/components/Breadcrumb/index.vue
create mode 100644 src/components/Hamburger/index.vue
delete mode 100644 src/components/HelloWorld.vue
create mode 100644 src/components/SvgIcon/index.vue
create mode 100644 src/layout/components/AppMain.vue
create mode 100644 src/layout/components/Navbar.vue
create mode 100644 src/layout/components/Sidebar/Link.vue
create mode 100644 src/layout/components/Sidebar/Logo.vue
create mode 100644 src/layout/components/Sidebar/SidebarItem.vue
create mode 100644 src/layout/components/Sidebar/index.vue
create mode 100644 src/layout/components/index.ts
create mode 100644 src/layout/mixin/ResizeHandler.ts
create mode 100644 src/store/modules/app.ts
create mode 100644 src/utils/validate.ts
diff --git a/README.md b/README.md
index 2218fed..d33d095 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ npm run dev
npm install vue-router@next
```
-src 下创建 router/index.ts
+src 下创建 router/interface.ts
```typescript
import {createRouter, createWebHashHistory, RouteRecordRaw} from 'vue-router'
@@ -71,7 +71,7 @@ export default router
npm install vuex@next
```
-src 下创建 store/index.ts
+src 下创建 store/interface.ts
```typescript
import {InjectionKey} from 'vue'
diff --git a/package.json b/package.json
index 3005ed7..a158d0e 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"dependencies": {
"axios": "^0.24.0",
"element-plus": "^1.2.0-beta.3",
+ "path-to-regexp": "^6.2.0",
"vue": "^3.2.16",
"vue-router": "^4.0.12",
"vuex": "^4.0.2"
diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue
new file mode 100644
index 0000000..e3c3daf
--- /dev/null
+++ b/src/components/Breadcrumb/index.vue
@@ -0,0 +1,103 @@
+
+
+
+
+
+ {{ item.meta.title }}
+
+ {{ item.meta.title }}
+
+
+
+
+
+
+
+
diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue
new file mode 100644
index 0000000..368b002
--- /dev/null
+++ b/src/components/Hamburger/index.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
deleted file mode 100644
index 86b7718..0000000
--- a/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- 点击+1
-
-
-
-
-
diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue
new file mode 100644
index 0000000..b07ded2
--- /dev/null
+++ b/src/components/SvgIcon/index.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
new file mode 100644
index 0000000..f6a3286
--- /dev/null
+++ b/src/layout/components/AppMain.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
new file mode 100644
index 0000000..9921a1f
--- /dev/null
+++ b/src/layout/components/Navbar.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue
new file mode 100644
index 0000000..530b3d5
--- /dev/null
+++ b/src/layout/components/Sidebar/Link.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
new file mode 100644
index 0000000..040fab6
--- /dev/null
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
new file mode 100644
index 0000000..386f4c6
--- /dev/null
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ t("route." + item.meta.title)
+ }}
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
new file mode 100644
index 0000000..36f13a2
--- /dev/null
+++ b/src/layout/components/Sidebar/index.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/index.ts b/src/layout/components/index.ts
new file mode 100644
index 0000000..86e2d4c
--- /dev/null
+++ b/src/layout/components/index.ts
@@ -0,0 +1,3 @@
+export { default as Navbar } from './Navbar.vue'
+export { default as Sidebar } from './Sidebar/index.vue'
+export { default as AppMain } from './AppMain.vue'
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 11cade3..c1d3027 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -1,57 +1,93 @@
-
- Header
-
- Aside
-
-
-
-
- Footer
-
-
-
+
-
\ No newline at end of file
+
diff --git a/src/layout/mixin/ResizeHandler.ts b/src/layout/mixin/ResizeHandler.ts
new file mode 100644
index 0000000..e3a0326
--- /dev/null
+++ b/src/layout/mixin/ResizeHandler.ts
@@ -0,0 +1,63 @@
+import {userStore} from '@/store'
+import {computed, watch} from "vue";
+import { useRoute } from 'vue-router'
+const store = userStore()
+
+const {body} = document
+const WIDTH = 992 // refer to Bootstrap's responsive design
+
+
+export default function () {
+ const device = computed(() => {
+ return store.state.app.device
+ })
+
+ const sidebar = computed(() => {
+ return store.state.app.sidebar
+ })
+
+ const isMobile = () => {
+ const rect = body.getBoundingClientRect()
+ return rect.width - 1 < WIDTH
+ }
+
+ const resizeHandler = () => {
+ if (!document.hidden) {
+ store.dispatch('app/toggleDevice', isMobile() ? 'mobile' : 'desktop')
+ if (isMobile()) {
+ store.dispatch('app/closeSideBar', {withoutAnimation: true})
+ }
+ }
+ }
+
+ const resizeMounted = () => {
+ if(isMobile()){
+ store.dispatch('app/toggleDevice', 'mobile')
+ store.dispatch('app/closeSideBar', {withoutAnimation: true})
+ }
+ }
+ const addEventListenerOnResize = () => {
+ window.addEventListener('resize', resizeHandler)
+ }
+
+ const removeEventListenerResize = () => {
+ window.removeEventListener('resize', resizeHandler)
+ }
+
+
+ const currentRoute = useRoute()
+ const watchRouter = watch(() => currentRoute.name, () => {
+ if (store.state.app.device === 'mobile' && store.state.app.sidebar.opened) {
+ store.dispatch('app/closeSideBar', false)
+ }
+ })
+
+ return {
+ device,
+ sidebar,
+ resizeMounted,
+ addEventListenerOnResize,
+ removeEventListenerResize,
+ watchRouter
+ }
+}
diff --git a/src/store/index.ts b/src/store/index.ts
index 1368867..5b335b8 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -1,24 +1,25 @@
import {InjectionKey} from 'vue'
import {createStore,useStore as baseUseStore ,Store} from 'vuex'
+import {RootStateTypes} from "@store/interface";
-export interface State {
- count: number
+// Vite 使用特殊的 import.meta.glob 函数从文件系统导入多个模块
+// see https://cn.vitejs.dev/guide/features.html#glob-import
+const moduleFiles = import.meta.globEager('./modules/*.ts')
+const paths:string[]=[]
+
+for (const path in moduleFiles) {
+ paths.push(path)
}
-export const key: InjectionKey> = Symbol()
+const modules = paths.reduce((modules: { [x: string]: any }, modulePath: string) => {
+ const moduleKey = modulePath.replace(/^\.\/modules\/(.*)\.\w+$/, '$1');
+ modules[moduleKey] = moduleFiles[modulePath].default;
+ return modules;
+}, {});
-export const store = createStore({
- state() {
- return {
- count: 0
- }
- },
- mutations: {
- increment(state: { count: number }) {
- state.count++
- }
- }
-})
+export const key: InjectionKey> = Symbol()
+
+export const store = createStore({modules})
export function userStore(){
return baseUseStore(key)
diff --git a/src/store/interface.ts b/src/store/interface.ts
index 8350855..817987a 100644
--- a/src/store/interface.ts
+++ b/src/store/interface.ts
@@ -8,7 +8,16 @@ export interface UserState {
}
+export interface AppState {
+ device: string,
+ sidebar: {
+ opened: boolean,
+ withoutAnimation: boolean
+ }
+}
+
// 顶级类型声明
export interface RootStateTypes {
- user: UserState
+ user: UserState,
+ app:AppState
}
\ No newline at end of file
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
new file mode 100644
index 0000000..6670c71
--- /dev/null
+++ b/src/store/modules/app.ts
@@ -0,0 +1,47 @@
+import {Module} from "vuex";
+import {RootStateTypes, AppState} from "@store/interface";
+import {Local} from "@utils/storage";
+
+const appModule: Module = {
+ namespaced: true,
+ state: {
+ device: 'desktop',
+ sidebar: {
+ opened: Local.get('sidebarStatus') ? !!+Local.get('sidebarStatus') : true,
+ withoutAnimation: false
+ }
+ },
+ mutations: {
+ TOGGLE_SIDEBAR: state => {
+ state.sidebar.opened = !state.sidebar.opened
+ state.sidebar.withoutAnimation = false
+ if (state.sidebar.opened) {
+ Local.set('sidebarStatus', 1)
+ } else {
+ Local.set('sidebarStatus', 0)
+ }
+ },
+ CLOSE_SIDEBAR: (state, withoutAnimation) => {
+ Local.set('sidebarStatus', 0)
+ state.sidebar.opened = false
+ state.sidebar.withoutAnimation = withoutAnimation
+ },
+ TOGGLE_DEVICE: (state, device) => {
+ state.device = device
+ }
+ },
+ actions: {
+ toggleSideBar({commit}) {
+ commit('TOGGLE_SIDEBAR')
+ },
+ closeSideBar({commit}, {withoutAnimation}) {
+ commit('CLOSE_SIDEBAR', withoutAnimation)
+ },
+ toggleDevice({commit}, device) {
+ commit('TOGGLE_DEVICE', device)
+ }
+ }
+}
+
+export default appModule;
+
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index 4b1d280..48cf5af 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -1,8 +1,7 @@
import {Module} from "vuex";
import {UserState, RootStateTypes} from "@store/interface";
import {Local} from "@utils/storage";
-import {getUserInfo, login,logout} from "@api/login"
-
+import {getUserInfo, login, logout} from "@api/login"
const getDefaultState = () => {
return {
@@ -14,7 +13,6 @@ const getDefaultState = () => {
}
}
-
const userModule: Module = {
namespaced: true,
state: {
@@ -104,12 +102,12 @@ const userModule: Module = {
/**
* 注销
*/
- logout({commit,state}){
+ logout({commit, state}) {
return new Promise(((resolve, reject) => {
- logout().then(()=>{
+ logout().then(() => {
Local.remove('token')
commit('RESET_STATE')
- }).catch(error=>{
+ }).catch(error => {
reject(error)
})
}))
diff --git a/src/utils/validate.ts b/src/utils/validate.ts
new file mode 100644
index 0000000..e35c2fa
--- /dev/null
+++ b/src/utils/validate.ts
@@ -0,0 +1,12 @@
+/**
+ * Created by PanJiaChen on 16/11/18.
+ */
+
+/**
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path : string) {
+ return /^(https?:|mailto:|tel:)/.test(path)
+}
+