cn域名做网站,最新国际新闻事件今天,营销型企业网站有哪些,广东住房城乡建设厅网站1.引言
路由拦截#xff0c;个人理解就是在页面跳转的时候#xff0c;增加一级拦截器#xff0c;实现一些自定义的功能#xff0c;其中最重要的就是判断跳转的页面是否需要登录后查看#xff0c;如果需要登录后查看且此时系统并未登录#xff0c;就需要跳转到登录页个人理解就是在页面跳转的时候增加一级拦截器实现一些自定义的功能其中最重要的就是判断跳转的页面是否需要登录后查看如果需要登录后查看且此时系统并未登录就需要跳转到登录页登录后跳转到原来想要访问的页面。
2.实现
uni-app的路由跳转分别是uni.navigateTo保留当前页面跳转到应用内的某个页面使用uni.navigateBack可以返回到原页面uni.redirectTo关闭当前页面跳转到应用内的某个页面uni.reLaunch关闭所有页面打开到应用内的某个页面uni.switchTab跳转到 tabBar 页面并关闭其他所有非 tabBar 页面uni.navigateBack关闭当前页面返回上一页面或多级页面可通过 getCurrentPages() 获取当前的页面栈决定需要返回几层。
在进行路由跳转时通过uni.addInterceptor添加拦截器实现路由拦截。 拦截是否需要登录的基本思路是通过pages.json文件对应的配置needLogin进行页面的配置在拦截时找到有此配置的所有页面得到所有页面的路径和本次访问的路径进行匹配如果匹配成功则判断当前是否是登录状态若没有登录跳转到登录界面进行登录。 3.代码
代码主要分为拦截器代码登录页pages配置登录页登录按钮功能。
1.拦截器代码
/*** by 菲鸽 on 2024-03-06* 路由拦截通常也是登录拦截* 可以设置路由白名单或者黑名单看业务需要选哪一个* 我这里应为大部分都可以随便进入所以使用黑名单*/
import { useUserStore } from /store
import { getNeedLoginPages, needLoginPages as _needLoginPages } from /utils
import { getAccessToken } from /utils/auth// 登录页面路径
const loginRoute /pages/login/indexconst isLogined () {const userStore useUserStore()return userStore.userInfo.isLogin getAccessToken()
}const isDev import.meta.env.DEV// 黑名单登录拦截器 - 适用于大部分页面不需要登录少部分页面需要登录
const navigateToInterceptor {// 注意这里的url是 / 开头的如 /pages/index/index跟 pages.json 里面的 path 不同invoke({ url }: { url: string }) {console.log(url) // /pages/route-interceptor/index?namefeigeage30const path url.split(?)[0]let needLoginPages: string[] []// 为了防止开发时出现BUG这里每次都获取一下。生产环境可以移到函数外性能更好if (isDev) {needLoginPages getNeedLoginPages()} else {needLoginPages _needLoginPages}const isNeedLogin needLoginPages.includes(path)if (!isNeedLogin || isLogined()) {return true}const redirectRoute ${loginRoute}?redirect${encodeURIComponent(url)}console.log(redirectRoute)uni.navigateTo({ url: redirectRoute })return false},
}export const routeInterceptor {install() {uni.addInterceptor(navigateTo, navigateToInterceptor)uni.addInterceptor(reLaunch, navigateToInterceptor)uni.addInterceptor(redirectTo, navigateToInterceptor)},
}2.辅助函数代码
import { pages, subPackages, tabBar } from /pages.json
export const getLastPage () {// getCurrentPages() 至少有1个元素所以不再额外判断// const lastPage getCurrentPages().at(-1)// 上面那个在低版本安卓中打包回报错所以改用下面这个【虽然我加了src/interceptions/prototype.ts但依然报错】const pages getCurrentPages()return pages[pages.length - 1]
}/** 判断当前页面是否是tabbar页 */
export const getIsTabbar () {if (!tabBar) {return false}if (!tabBar.list.length) {// 通常有tabBar的话list不能有空且至少有2个元素这里其实不用处理return false}const lastPage getLastPage()const currPath lastPage.routereturn !!tabBar.list.find((e) e.pagePath currPath)
}/*** 获取当前页面路由的 path 路径 和 redirectPath 路径* path 如 ‘/pages/login/index’* redirectPath 如 ‘/pages/demo/base/route-interceptor’*/
export const currRoute () {const lastPage getLastPage()const currRoute (lastPage as any).$page// console.log(lastPage.$page:, currRoute)// console.log(lastPage.$page.fullpath:, currRoute.fullPath)// console.log(lastPage.$page.options:, currRoute.options)// console.log(lastPage.options:, (lastPage as any).options)// 经过多端测试只有 fullPath 靠谱其他都不靠谱const { fullPath } currRoute as { fullPath: string }// console.log(fullPath)// eg: /pages/login/index?redirect%2Fpages%2Fdemo%2Fbase%2Froute-interceptor (小程序)// eg: /pages/login/index?redirect%2Fpages%2Froute-interceptor%2Findex%3Fname%3Dfeige%26age%3D30(h5)return getUrlObj(fullPath)
}const ensureDecodeURIComponent (url: string) {if (url.startsWith(%)) {return ensureDecodeURIComponent(decodeURIComponent(url))}return url
}
/*** 解析 url 得到 path 和 query* 比如输入url: /pages/login/index?redirect%2Fpages%2Fdemo%2Fbase%2Froute-interceptor* 输出: {path: /pages/login/index, query: {redirect: /pages/demo/base/route-interceptor}}*/
export const getUrlObj (url: string) {const [path, queryStr] url.split(?)// console.log(path, queryStr)if (!queryStr) {return {path,query: {},}}const query: Recordstring, string {}queryStr.split().forEach((item) {const [key, value] item.split()// console.log(key, value)query[key] ensureDecodeURIComponent(value) // 这里需要统一 decodeURIComponent 一下可以兼容h5和微信y})return { path, query }
}
/*** 得到所有的需要登录的pages包括主包和分包的* 这里设计得通用一点可以传递key作为判断依据默认是 needLogin, 与 route-block 配对使用* 如果没有传 key则表示所有的pages如果传递了 key, 则表示通过 key 过滤*/
export const getAllPages (key needLogin) {// 这里处理主包const mainPages [...pages.filter((page) !key || page[key]).map((page) ({...page,path: /${page.path},})),]// 这里处理分包const subPages: any[] []subPackages.forEach((subPageObj) {// console.log(subPageObj)const { root } subPageObjsubPageObj.pages.filter((page) !key || page[key]).forEach((page: { path: string } Recordstring, any) {subPages.push({...page,path: /${root}/${page.path},})})})const result [...mainPages, ...subPages]// console.log(getAllPages by ${key} result: , result)return result
}/*** 得到所有的需要登录的pages包括主包和分包的* 只得到 path 数组*/
export const getNeedLoginPages (): string[] getAllPages(needLogin).map((page) page.path)/*** 得到所有的需要登录的pages包括主包和分包的* 只得到 path 数组*/
export const needLoginPages: string[] getAllPages(needLogin).map((page) page.path)3.需要登录页面配置
route langjson5
{style: {navigationBarTitleText: 办公,},needLogin: true,
}
/route
templateview classbg-white overflow-hidden pt-2 px-4view123/view/view
/templatescript setup langts/scriptstyle langscss/style
能在组件中配置页面的信息主要得益于uni-helper/vite-plugin-uni-pages 插件的功劳该插件由 uni-helper 官方团队开发可参考uni 插件 | unibest。
4.登录按钮功能
// 登录系统 一进系统就需要登录
const handleLogin async () {const loginRes await loginApi.login(loginForm)console.log(loginRes)setAccessToken(loginRes.data.accessToken)setRefreshToken(loginRes.data.refreshToken)// 获取路由路径 进行跳转const fullPath currRoute()console.log(fullPath)uni.redirectTo({ url: fullPath.query.redirect })
}
登录按钮就是获取登录数据存储token重定向至原来访问的界面。
4.功能展示 uni-app登录验证 5.写在最后
本文首先感谢unibestuniapp 开发框架在unibest项目基础上添加了一些小的功能基本能满足路由跳转时的拦截为后续业务的权限管理打下坚实基础。
本文如有疏漏之处欢迎批评指正。