前言
书接上文,因为刚开发时的想法有点问题,所以框架也就有点小问题,但是能用。
登录
登录系统的有三种人,游客、读者、管理员。登录的权限判断使用vue-router的全局路由守卫。
router.beforeEach(async(to) => {
const hasToken = getToken()
if (hasToken) {
if (to.path === "/login") {
return "/"
} else {
const hasGetUserInfo = store.getters.roles || []
if (hasGetUserInfo.length) {
return true
} else {
try {
await store.dispatch("user/getInfo").then(res => {
const roles = res.data.roles
store.dispatch("permission/generateRoutes", roles).then((accessedRoutes) => {
accessedRoutes.map(item => {
router.addRoute(item)
})
router.push(to.path)// hack方法 确保addRoutes已完成
return true
})
})
} catch (error) {
}
}
}
} else {
store.dispatch("permission/initRoutes")
}
})
逻辑很简单,但是这里需要注意的是,try、catch是无法捕获异步行为的错误的,例如Promise。如果想用的话就要如上使用await。
layout
layout由三部分构成,分别是main、navbar、siderbar,下面为预览。
siderbar
siderbar已经在前面总结过了。
<template>
<div :class="classObj"
class="app-wrapper">
<sidebar class="sidebar-container" />
<div class="main-container">
<navbar />
<app-main />
</div>
</div>
</template>
const classObj = computed(() => {
return {
hideSidebar: store.getters.isCollapse,
openSidebar: !store.getters.isCollapse
}
})
这里classObj通过vuex里的isCollapse判断是否折叠siderbar。
AppMain
AppMain这里是vue3的统一写法了,当时用transition和keep-alive时。以后的路由组件都会显示在这里。
<template>
<section class="app-main">
<router-view v-slot="{Component}">
<transition name="fade-transform"
mode="out-in">
<keep-alive :include="[]">
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
</section>
</template>
Navbar
Navbar其实并没有什么实际意义,主要就是提供一个breadcrumb和刷新后退的功能,前者官网的教程很详细,稍微说一下刷新功能。
主要是通过一个redirect路由组件来实现,这个组件在别的地方也有用到。
//redirect.vue
setup() {
const route = useRoute()
const router = useRouter()
const { params, query } = route
const { path } = params
router.replace({ path: "/" + path, query })
}
//navbar.vue
function refresh() {
router.replace({
path: "/redirect" + route.fullPath
})
}
//index.js
{
path: "/redirect",
component: Layout,
hidden: true,
children: [{
name: "redirect",
path: "/redirect/:path(.*)",
component: () =>
import ("@/views/redirect/index")
}]
},
path: "/redirect/:path(.*)"会把/redirect后的东西当成params传给redirect组件,当然对应的你在路由传递参数时就不能使用params而是要使用query。
剩下的说白了就是把路径传给redirect组件,然后在redirect里重定向至原页面。
还有需要注意的就是appmain里的include="[]"不能包括redirect组件,否则redirect组件不能正常工作
axios封装
这里也是每次项目直接CV然后微微改动就行的部分。
import axios from "axios"
import store from "@/store"
const service = axios.create({
baseURL: process.env.NODE_ENV === "development" ? "http://****" : "https://*****",
timeout: 5000
})
service.interceptors.request.use(
config => {
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
service.interceptors.response.use(
response => {
const res = response.data
if (res.code !== 0) {
if (response.config.url === "/pay") return response
return Promise.reject(new Error(res.message || "Error"))
} else {
return res
}
},
error => {
console.log("err" + error) // for debug
return Promise.reject(error)
}
)
export default service
结语
写的时候感觉写了很久,事后总结起来感觉好像也就只弄了这么一点点内容而已....