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 @@ + + + + + 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 @@ - - - - - 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 @@ + + + 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 @@ - \ 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) +} +