vue3 中的导航守卫与 vue2 中的基本一致,不同的地方在于,vue3 中导航守卫取消了 next 参数,而是通过返回 false 来取消路由跳转。
以前置路由守卫为例,结合 sessionStorage 实现获取 token 值之后跳转到后台管理页面。
配置路由及守卫:
// vue-router中提供3种的路由模式
import { createWebHistory, createRouter } from 'vue-router'const routes = [{path: '/login',component: () => import('@/views/login.vue')},{path: '/admin',component: () => import('@/views/admin.vue'),meta: {isLogin: true}}
] const router = createRouter({// 路由的模式history: createWebHistory(),// 路由规则routes
})// 全局前置守卫
router.beforeEach((to, from) => {// 验证指定的页面无须登录就可以访问// 1.可以通过path路由来区别// 2.meta来完成区别// console.log('前置全局守卫', to.path);// console.log('前置全局守卫', to.meta.isLogin);// 如果此页面需要登录才能访问到,就需要来判断当前的本地存储中是否有tokenif (!to.meta.isLogin) {return true}// 如下的页面一定要求用户登录才能访问到if (!sessionStorage.getItem('token')) {// 跳转到登录页// return '/login'// 跳转后不能回退return { path: '/login', replace: true }}return true
})export default router
mock 假数据:
import Mockjs from 'mockjs'const mockData = [{url: '/api/login',method: 'post',response: () => ({code: 0,msg: 'ok',data: {uid: 1000,nickname: '张三',token: 'afewlfjewlfjewlfejlfejl;fejlf;e'}})}
]export default mockData
登录页:
登录页面
后台管理页:
后台管理
安装:
yarn add vuex
使用:
首先为 vuex 创建 store 目录(store/index.js):
import { createStore } from 'vuex'// const store = createStore({
// state: {
// num: 100
// }
// })// 如果你现在用的是基于vue的服务器端渲染,此时一定要写成回调函数方案
const store = createStore({state: () => ({num: 100}),mutations: {setNum(state, payload) {state.num += payload}},actions: {asyncSetNum({ commit }, payload) {setTimeout(() => {commit('setNum', payload)}, 1000);}}
})export default store
在入口文件(main.js)处引入 vuex:
// 创建vue入口程序,由原来的类实例,变成现在的函数方式,为了更好在打包时优化代码
import { createApp } from 'vue'
// 根组件
import App from './App.vue'
// 路由
import router from './router'
// vuex
import store from './store'import createGlobalComponent from './components'
import globalProperties from './config/globalProperties'// 实例化一个Vue顶层组件
// const app = createApp(App)// 创建全局组件
// // createGlobalComponent(app)
// app.use(createGlobalComponent)
// app.use(globalProperties)
// // 路由
// app.use(router)
// // vuex
// app.use(store)
// app.mount('#app')// 工作中常用写法:
createApp(App).use(createGlobalComponent).use(globalProperties).use(router).use(store).mount('#app')
关于页面:
关于页面 -- {{ num }}
store/modules/count.js:
export default {// 开启强制命名空间namespaced: true,state: () => ({num: 100}),mutations: {setNum(state, payload) {state.num += payload}},actions: {asyncSetNum({ commit }, payload) {setTimeout(() => {commit('setNum', payload)}, 1000);}}
}
store/modules/user.js:
export default {// 开启强制命名空间namespaced: true,state: () => ({uid: 0,nickname: '',token: ''}),mutations: {login(state, payload) {state.uid = payload.uidstate.nickname = payload.nicknamestate.token = payload.tokensessionStorage.setItem('token', payload.token)}},actions: {}
}
store/index.js:
import { createStore, useStore } from 'vuex'import count from './modules/count'
import user from './modules/user'// 如果你现在用的是基于vue的服务器端渲染,此时一定要写成回调函数方案
const store = createStore({modules: {count,user}
})export default store
关于页面:
关于页面 -- {{ num }}
登录页面:
登录页面
对 store 的入口文件中模块的导出作修改(对 useStore 做二次封装后导出)、对登录页面模块的导入作修改。
store/index.js:
import { createStore, useStore } from 'vuex'import count from './modules/count'
import user from './modules/user'// 如果你现在用的是基于vue的服务器端渲染,此时一定要写成回调函数方案
const store = createStore({modules: {count,user}
})// 方式二导出
export const useUserStateStore = () => {let store = useStore()return [store.state.user, store.commit, store.dispatch]
}export default store
登录页面:
登录页面
在方式二的基础上,将 store/index.js 文件中的方法,拆分开导入。
store/index.js:
import { createStore, useStore } from 'vuex'import count from './modules/count'
import user from './modules/user'// 如果你现在用的是基于vue的服务器端渲染,此时一定要写成回调函数方案
const store = createStore({modules: {count,user}
})export const useUserState = () => {let store = useStore()return store.state.user
}export const useCommit = () => {let store = useStore()return store.commit
}export const useDispatch = () => {let store = useStore()return store.dispatch
}export default store
登录页面:
登录页面
import { createStore, useStore } from 'vuex'// 自动导入模块
// eager 同步,不能使用 promise
const moduleFiles = import.meta.glob('./modules/*', { eager: true })
let modules = {}
for (let key in moduleFiles) {let prop = /\.\/modules\/(\w+)\.js/.exec(key)[1]let value = moduleFiles[key].defaultmodules[prop] = value
}// 如果你现在用的是基于vue的服务器端渲染,此时一定要写成回调函数方案
const store = createStore({modules
})export const useUserState = () => {let store = useStore()return store.state.user
}export const useCommit = () => {let store = useStore()return store.commit
}export const useDispatch = () => {let store = useStore()return store.dispatch
}export default store
上一篇:旋转的骰子(二)