#author("2022-12-25T16:08:01+08:00","default:Admin","Admin") #author("2022-12-26T10:50:15+08:00","default:Admin","Admin") [[uni-app]] &color(red){※前提条件:vue3 的uniapp开发}; #contents *概要 [#cbd93c54] 当某些页面需要登录,进入之前需要判断是否登录,如果没有登录则跳转到登录页。可以封装公共方法或混入实现,但是不太优雅,这时使用路由守卫实在是太方便了 &color(red){注意:}; 截止之前的版本,在 app 端都无法做到拦截首屏加载的问题。v1.4.8 发布后将会拦截首屏处理,并自动注册首屏页面触发生命周期。首次打开app则会触发,你可以在里面做什么想完成的操作。启动页不支持nvue,以此则会出现白屏现象。永远进不去APP。 官网 https://hhyang.cn/src/router/start/introduction.html Github https://github.com/SilurianYang/uni-simple-router * 安装 [#jda4edcb] 安装uni-simple-router插件 npm install uni-simple-router 配合vue.config.js自动读取pages.json作为路由表的方式 npm install uni-read-pages * 配置 [#f0a2785b] ** /main.js [#z553d71b] #codeprettify{{ import App from './App' import Vue from 'vue' import {router,RouterMount} from './router/router.js' Vue.use(router) // #ifndef VUE3 Vue.config.productionTip = false App.mpType = 'app' const app = new Vue({ ...App }) //v1.3.5起 H5端 你应该去除原有的app.$mount();使用路由自带的渲染方式 // #ifdef H5 RouterMount(app,router,'#app') // #endif // #ifndef H5 app.$mount(); //为了兼容小程序及app端必须这样写才有效果 // #endif }} ** /router/router.js [#k4e4d98f] - 一定添加 path: '*' 否则:报错Error: / 路径无法在路由表中找到,检查跳转路径及路由表 - 发生错误时,需要使用 router.$lockStatus = false; 来解锁,否则后续无法正常跳转 #codeprettify{{ // router/router.js import {RouterMount, createRouter} from 'uni-simple-router'; const router = createRouter({ platform: process.env.VUE_APP_PLATFORM, routes: [...ROUTES, { path: '*' // 不需要配置跳转路由 // redirect:(to)=>{ // return {name:'404'} //} }, ], routerErrorEach: ({ type, msg }) => { console.log({ type, msg }) // ②优雅解锁 error.type: //0 表示 next(false)//"type":0,"msg":"管道函数传递 false 导航被终止!" //1表示next(unknownType) //2表示加锁状态,禁止跳转 //"当前页面正在处于跳转状态,请稍后再进行跳转.... //3表示在获取页面栈时,页面栈不够level获取 router.$lockStatus = false; // #ifdef APP-PLUS if (type === 3) { //{"type":3,"msg":"不存在的页面栈,请确保有足够的页面可用,当前 level:1"} plus.runtime.quit(); } // #endif }, }); //全局路由前置守卫 router.beforeEach((to, from, next) => { //权限控制登录 // if(to.meta.auth){ // console.log("需要登录"); // if("token"){ // next(); // }else{ // console.log("请登录"); // } // }else{ // console.log("不需要登录"); // next(); // } console.log("前置守卫" + JSON.stringify(to)); next(); }); // 全局路由后置守卫 router.afterEach((to, from) => { console.log('跳转结束') }) export { router, RouterMount } }} ** /pages.json [#v98653a5] &color(red){对于h5端你必须在首页加上aliasPath并设置为 /}; #codeprettify{{ { "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { //首页 "path": "pages/index/index", "aliasPath": "/", //对于h5端你必须在首页加上aliasPath并设置为/ "name": "index", "style": { "navigationBarTitleText": "uni-app" } }, ... }} ** /vue.config.js [#ofa93a43] uni-read-pages插件用在这里 &color(red){注意:修改之后一定要重新编译(hBuilder预览关闭后,再次打开即可),差量编译不会生效}; #codeprettify{{ // vue.config.js const TransformPages = require('uni-read-pages') const { webpack } = new TransformPages() module.exports = { configureWebpack: { plugins: [ new webpack.DefinePlugin({ ROUTES: webpack.DefinePlugin.runtimeValue(() => { console.log('打印一下'); const tfPages = new TransformPages({ includes: ['path', 'name', 'aliasPath','meta'] }); return JSON.stringify(tfPages.routes) }, true) }) ] } } }} ***DefinePlugin [#gdad9910] webpack插件之DefinePlugin - 允许创建一个 在编译时可以配置的全局变量 - 场景:区分不同开发模式处理 #codeprettify{{ // 1用法:每个传进DefinePlugin的键值都是一个标志或者多个用.连接起来的标识符 new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(true), BROWSER_SUPPRTS_HTML5: true, VERSION: JSON.stringify('abcde'), TWO: '1+1', 'typeof window': JSON.stringify('object') }) // 使用方式 console.log('Running App version', VERSION) if(!BROWSER_SUPPRTS_HTML5) require("html5shiv") // 2功能标记 来作为一个flag标识启用和禁用构建中的功能 new webpack.DefinePlugin({ 'SHOW_PRESSION': JOSN.string(true) }) // 3服务:可以配置不同环境下的url new webpack.DefinePlugin({ 'DEV_URL': JSON.stringify(url_dev), 'PRO_URL': JSON.stringify(url_pro) }) }} ** 组件内的守卫(可以不使用) [#k58e62ce] 这些守卫与全局前置守卫的方法参数是一样的 #codeprettify{{ <template> <view> <h1>路由守卫 beforeRouteLeave</h1> </view> </template> <script> export default { data() { return { }; }, beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` next(); }, } </script> }} * 使用 [#ma10fda7] ** 编程式导航 [#bc366951] 通过this.$Router获取路由对象;push、pushTab、replace、back等api进行路由跳转 注: - path搭配query参数、name搭配params参数 - 导航使用方式同vue-router 一般画面的跳转 #codeprettify{{ // 字符串 this.$Router.push('/pages/router/router1') // 对象 this.$Router.push({path:'/pages/router/router1'}) // 命名的路由 this.$Router.push({ name: 'router1', params: { userId: '123' }\}) // 带查询参数,变成 /router1?plan=private this.$Router.push({ path: 'router1', query: { plan: 'private' }\}) }} &color(red){如果跳转的页面是tarbar里面定义的页面的话使用}; #codeprettify{{ this.$Router.pushTab({name: 'home'}); }} 参考: https://hhyang.cn/src/router/start/cross/codeRoute.html ** 组件跳转 [#le89ce7d] vue-router中可以通过router-link组件进行页面跳转,uni-simple-router也提供了类似的组件,需要手动注册 #codeprettify{{ // main.js import Link from './node_modules/uni-simple-router/dist/link.vue' Vue.component('Link', Link) // 通过path直接跳转 并指定跳转类型 <Link to="/tabbar1" navType="pushTab"> <button type="primary">使用path对象跳转</button> </Link> }} * Troubleshooting [#e79b59f7] ** 画面跳转 [#g1ec2f31] 类似下面的错误 - 管道函数传递 false 导航被终止 - 当前页面正在处于跳转状态,请稍后再进行跳转.... pages.json的页面配置中的第一项会作为启动后的页面,那就将第一项配置为一个加载页(或者空白页,就是说别让不需要的东西显示出来) #hr(); Comment: #comment_kcaptcha