您现在的位置是:网站首页> 编程资料编程资料
uniapp路由uni-simple-router实例详解_javascript技巧_
2023-05-24
328人已围观
简介 uniapp路由uni-simple-router实例详解_javascript技巧_
uni-simple-router
- 专为uniapp打造的路由器,和uniapp深度集成
- 通配小程序、App和H5端
- H5能完全使用vue-router开发
- 模块化、查询、通配符、路由参数
- 使 uni-app实现嵌套路由(仅H5端完全使用vue-router)
- uniapp用到了很多vue的api,但在路由管理的功能相对于vue-router还是比较欠缺的,比如全局导航守卫
官方文档:https://hhyang.cn/v2/start/quickstart.html
一、快速上手
// 针对uniapp HBuilder创建的项目,非cli构建 // 1⃣ NPM 安装 npm install uni-simple-router // 2⃣ 初始化 npm install uni-read-pages // 配合vue.config.js自动读取pages.json作为路由表的方式,源码例如下:扩二 // 配置vue.config.js const TransformPages = require('uni-read-pages') const tfPages = new TransformPages() module.exports = { configureWebpack: { plugins: [ new tfPages.webpack.DefinePlugin({ // 1⃣ 配置全局变量 // ROUTES: JSON.stringify(tfPages.routes) // 2⃣ includes 可自定义,解析pages.json路由配字段的配置, 默认 ['path', 'name', 'aliasPath'] ROUTES: tfPages.webpack.DefinePlugin.runtimeValue(()=>{ const tf = new TransformPages({ includes: ['path', 'name', 'aliasPath'] }) return JSON.stringify(tfPages.routes) },true) }) ] } } // /Applications/HBuilderX.app/Contents/HBuilderX/plugins/uniapp-cli/node_modules/webpack 我的webpack包路径,在软件contents包文件里软件自带的webpack扩一:webpack插件之DefinePlugin
- 允许创建一个 在编译时可以配置的全局变量
- 场景:区分不同开发模式处理
// 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) }) 扩二:uni-read-pages 如何获取pages.json中的路由
// 依赖的源码 - 通过node的path模块获取pages.json文件中的任何信息 (部分是个人注释) const path = require('path') const CONFIG = { includes: ['path', 'aliasPath', 'name'] } // 默认获取路由参数属性 // process.cwd() 返回Node.js进程的当前工作目录 // path.resolve(url1, 'abc') => url1/abc const rootPath = path.resolve(process.cwd(), 'node_modules'); // 获取根路径 /** 解析绝对路径 * @param {Object} dir */ function resolvePath(dir) { return path.resolve(rootPath, dir); } // 类 class TransformPages { constructor(config) { // 组合 自定义获取配置属性 config = { ...CONFIG, ...config }; this.CONFIG = config; // ↓本机文件路径(HBuilderX包文件里自带的webpack模块路径) /Applications/HBuilderX.app/Contents/HBuilderX/plugins/uniapp-cli/node_modules/webpack this.webpack = require(resolvePath('webpack')); this.uniPagesJSON = require(resolvePath('@dcloudio/uni-cli-shared/lib/pages.js')); // TODO: 根据CONFIG解析pages.json中的路由信息 和 小程序 分包下的路由 this.routes = this.getPagesRoutes().concat(this.getNotMpRoutes()); } // 获取所有pages.json下的内容 返回json get pagesJson() { return this.uniPagesJSON.getPagesJson(); } // 通过读取pages.json文件 生成直接可用的routes getPagesRoutes(pages = this.pagesJson.pages, rootPath = null) { const routes = []; for (let i = 0; i < pages.length; i++) { const item = pages[i]; const route = {}; for (let j = 0; j < this.CONFIG.includes.length; j++) { const key = this.CONFIG.includes[j]; let value = item[key]; if (key === 'path') { value = rootPath ? `/${rootPath}/${value}` : `/${value}` } if (key === 'aliasPath' && i == 0 && rootPath == null) { route[key] = route[key] || '/' } else if (value !== undefined) { route[key] = value; } } routes.push(route); } return routes; } // 解析小程序分包路径 getNotMpRoutes() { const { subPackages } = this.pagesJson; let routes = []; if (subPackages == null || subPackages.length == 0) { return []; } for (let i = 0; i < subPackages.length; i++) { const subPages = subPackages[i].pages; const root = subPackages[i].root; const subRoutes = this.getPagesRoutes(subPages, root); routes = routes.concat(subRoutes) } return routes } /** * 单条page对象解析 * @param {Object} pageCallback * @param {Object} subPageCallback */ parsePages(pageCallback, subPageCallback) { this.uniPagesJSON.parsePages(this.pagesJson, pageCallback, subPageCallback) } } module.exports = TransformPages 二、H5模式
2.1 路由配置
import {RouterMount,createRouter} from 'uni-simple-router'; const router = createRouter({ // 路由配置 routes: [ { path: '/pages/index/index', // 必须和pages.json中相同 extra: { pageStyle: { color: '#f00' }// 及其它自定义参数 } } ] }) // 组件中可以通过 this.$Route 查看路由元信息 2.2 完全使用vue-router开发 (H5端)
嵌套路由时,若使用name方式跳转,仅支持 this.$router.push({ name: children1 })
// 使用 vue-router开发将会失去uniapp的生命周期 const router = createRouter({ h5: { vueRouterDev: true, // 完全使用vue-router开发 默认是false }, // 路由配置 routes: [ { path: '/', name: 'home', component: () => import('@/common/router/home.vue'), // 嵌套路由(仅H5端),小程序端会重新页面打开 children: [ { path: 'home/children1', name: 'children1', component: () => import('@/common/router/children1.vue') }, { path: 'home/children2', name: 'children2', component: () => import('@/common/router/children2.vue') } ] } ] }) 2.3 H5 路由传参
// 除vue-router外,美化url可以在基础配置时,定义aliasPath变量,设置路由别名(浏览器地址栏展示名称) // 别名的设置,如果设置了别名,通过push路径的方式,必须使用aliasPath的路径才能生效 const router = createRouter({ routes:[{ name:'router1', //为了兼容其他端,此时的path不能少,必须和 pages.json中的页面路径匹配 path: "/pages/tabbar/tabbar-1/tabbar-1", aliasPath: '/tabbar-1', },] }); // uni-simple-router路由跳转 // aliasPath命名的路由 => name传递参数需 params this.$Router.push({ name: 'detail', params: { id: 1 } }) // 带查询参数,变成 /home/id=1 => path 对应query,params失效 this.$Router.push({ path: '/pages/index/detail', query: { id: 1 }}) 2.4 H5端路由捕获所有路由或404路由
path:'*' // 通常用于客户端404错误,如果是history模式,需要正确配置服务器 path: '/detail-*' // 路由的优先级根据 定义的先后
2.5 路由懒加载
打包构建应用时,Javascript包会变得非常大,影响页面加载,把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件。
const Foo = () => import('./Foo.vue') // 把组件按组分块 使用 命名 chunk const Foo = () => import(/*webpackChunkName:"group-foo"*/ './Foo.vue') const Bar = () => import(/*webpackChunkName:"group-foo"*/ './Bar.vue') 三、小程序模式
注:小程序系列无法拦截原生tabbar及原生导航返回,如需拦截使用自定义tabbar、header
通过api进行切换时,像uni.switchTab()和this.$Router.pushTab()方法会触发拦截的;仅底部原生tabbar进行切换时不触发拦截
强制触发守卫:forceGuardEach(replaceAll, false) 每次调用api都会重新按流程触发已经声明的所有守卫
- 小程序端默认:插件api跳转、uni导航api跳转和首屏加载
- 使用路由守卫:通过点击事件强制触发、混入到onshow回调触发
跳转路由锁:animationDuration保留给redirection\push足够时间,等切换完成页面后才放行下次跳转
const router = createRouter({ platform: process.env.VUE_APP_PLATFORM, // ① 路由锁 applet: { animationDuration: 300 // 默认300ms // animationDuration: 0 // 不精准 只捕捉跳转api下的complete函数 }, // ②优雅解锁 error.type: 0 表示 next(false)、1表示next(unknownType)、2表示加锁状态,禁止跳转、3表示在获取页面栈时,页面栈不够level获取 routerErrorEach:(error, router) => { if (error.type === 3) { router.$lockStatus = false } }, routes: [...ROUTES] }) 四、路由跳转
4.1 组件跳转
vue-router中可以通过router-link组件进行页面跳转,uni-simple-router也提供了类似的组件,需要手动注册
// main.js import Link from './node_modules/uni-simple-router/dist/link.vue' Vue.component('Link', Link) // 通过path直接跳转 并指定跳转类型
4.2 编程式导航
- 通过this.$Router获取路由对象;push、pushTab、replace、back等api进行路由跳转
- 注:path搭配query参数、name搭配params参数
- 导航使用方式同vue-router
五、跨平台模式
5.1 提前享用生命周期
uniapp由于只用onLoad接受options参数、onShow不接受;传递深度对象参数时,需要先编码再传递解码
// 动态改变参数 使
相关内容
- 关于Vue-cli3烦人的eslint问题_vue.js_
- Vue 中的 computed 和 watch 的区别详解_vue.js_
- 解决VuePress页面乱码问题_vue.js_
- JavaScript中执行上下文和执行栈_javascript技巧_
- vue中的公共方法调用方式_vue.js_
- Vue3初探之ref、reactive以及改变数组的值_vue.js_
- vue-devtools 打开源码位置实现过程_vue.js_
- js 实现Material UI点击涟漪效果示例_JavaScript_
- js 实现验证码输入框示例详解_JavaScript_
- react中代码块输出,代码高亮显示,带行号,能复制的问题_React_
点击排行
本栏推荐
