笔记中的内容仅实用于HBulider构建的uniapp我的项目,通过其余形式构建的uniapp我的项目请参考uni-simple-router官网 uni-simple-router (hhyang.cn)

uniapp用到了vue的很多api,但在路由治理的性能上相较于vue-router还是比拟欠缺的,比方全局导航守卫。

咱们能够通uniapp的插件uni-simple-router来实现相似于vue-router的性能,但多端兼容时,一些用法还须要留神,咱们会讲到。

一、装置

如果你的我的项目没有应用package,请先初始化:

$ npm init -y

装置依赖:

$ npm install uni-simple-router uni-read-pages
uni-read-pages的作用是:读取uniapp的pages.json,作为router的配置,把pages.json中的路由配置转换成vue-router配置的模式。

二、配置与初始化

1、根目录新建 vue.config.js 文件,写入以下内容:

//vue.config.jsconst TransformPages = require('uni-read-pages')const {webpack} = new TransformPages()module.exports = {    configureWebpack: {        plugins: [            new webpack.DefinePlugin({                ROUTES: webpack.DefinePlugin.runtimeValue(() => {                    const tfPages = new TransformPages({                        includes: ['path', 'name', 'aliasPath']                    });                    return JSON.stringify(tfPages.routes)                }, true )            })        ]    }}

⚠️ 其中要重点关注第 10 行:

// ...    includes: ['path', 'name', 'aliasPath']// ...

includes 中蕴含的是router会读取pages路由中的字段名,后续如果有用到meta等路由信息,能够在 includes 里减少 'meta',在pages路由中写对应的数据,router中就能够获取失去(前面再补充案例)

2、根目录新建并写入router.js,写入以下内容:

// router.jsimport {RouterMount,createRouter} from 'uni-simple-router';const router = createRouter({    platform: process.env.VUE_APP_PLATFORM,      routes: [...ROUTES]});//全局路由前置守卫router.beforeEach((to, from, next) => {    next();});// 全局路由后置守卫router.afterEach((to, from) => {    console.log('跳转完结')})export {    router,    RouterMount}

3、main.js导入router.js并挂载

// main.jsimport Vue from 'vue'import App from './App'import {router,RouterMount} from './router.js'  //门路换成本人的Vue.use(router)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
!!留神app的挂载形式,必须依照这里的写法实现!

4、从新编译运行

三、路由跳转

办法一:组件跳转

vue-router中能够通过 <router-link></router-link> 组件进行页面跳转,uni-simple-router也提供了相似的组件:只不过这个组件须要手动注册

// main.jsimport Mylink from './node_modules/uni-simple-router/dist/link.vue'     Vue.component('my-link',Mylink)
注册组件时留神,组件的名称不要和 pages.json 中的 easycom 属性规定抵触,否则会找easycom门路下的组件,从而找不到组件报错。
<!-- 通过path间接跳转 并指定跳转类型 --><my-link to="/tabbar-4" navType="pushTab">  <button type="primary">应用path对象跳转</button></my-link>
组件的残缺属性,能够在文档中找到:
Router 构建选项 | uni-simple-router (hhyang.cn)

办法二:编程式导航:

在vue示例中,通过 this.$Router 获取路由对象(R必须大写),编程式导航与vue-router很靠近,但仍有须要留神的中央,具体能够参考文档.

⚠️ 必须留神的点:
在vue我的项目中,跳转路由时常常应用name进行跳转,相比于path,name更简洁、会被扭转的几率也更小。

然而在uniapp中就要注意了,如果你要应用name进行跳转,那就无奈携带query参数!同理,应用path跳转也不能应用params参数

// 以下是谬误的写法,name不能搭配query应用,path也不能搭配params参数应用this.$Router.push({ name: 'newsDetail', query: { id: '123' }})this.$Router.push({ path: '/pages/news/detail', params: { id: '123' }})// 以下是正确的写法:this.$Router.push({ name: 'newsDetail', params: { id: '123' } })this.$Router.push({ path: '/pages/news/detail',query: { id: '123' }})

总之:记住:path搭配query参数,name搭配params参数

四、APP退出利用

在app路由栈已达到最底层时,再次点击退出程序是十分常见的性能,咱们能够这样实现:

// router.js文件import {    RouterMount,    createRouter,    runtimeQuit} from './dist/uni-simple-router.js';// runtimeQuit记得导入const router = createRouter({    platform: process.env.VUE_APP_PLATFORM,      routerErrorEach:({type,msg})=>{        console.log({type,msg})        // #ifdef APP-PLUS            if(type===3){                router.$lockStatus=false;                runtimeQuit();            }        // #endif    },    routes: [...ROUTES]});

routerErrorEach中,type的含意如下:

  • 0 示意 next(false)
  • 1 示意 next(unknownType)
  • 2 示意加锁状态,禁止跳转
  • 3 示意在获取页面栈的时候,页面栈不够level获

除了再次点击退出外,你还能够实现本人的逻辑,比方弹窗提醒退出等:

const router = createRouter({    platform: process.env.VUE_APP_PLATFORM,      routerErrorEach:({type,msg})=>{        console.log({type,msg})        // #ifdef APP-PLUS            if(type===3){                router.$lockStatus=false;                uni.showModal({                            title: '提醒',                            content: '您确定要退出利用吗?',                            success: function (res) {                                if (res.confirm) {                                    plus.runtime.quit();                                }                             }                        });            }        // #endif    },    routes: [...ROUTES]});

五、Route对象

和vue-router一样,uniapp在页面中也能获取以后的页面路由信息,不过首字母改成了大写字母:

onLoad() {    console.log(this.$Route)}

$Route 中蕴含了路由的根本信息以及,vue.config.js配置中includes配置的字段,和导航守卫中的to/from对象统一,利用includes配置项和导航守卫,能够实现权限校验的配置:

// router.jsrouter.beforeEach((to, from, next) => {    if (to.meta && to.meta.power === "public") { // 公共页面,不须要登录            } else { // 须要登录的页面             let isLogin = checkLogin(); // 判断是否登录        if (isLogin) {            next();        } else {            next({                name: "login"            })        }    }});
// pages.json"pages": [        {            "path": "pages/login/login",            "name": "login",            "desc": "登录页",            "meta": {                "power": "public" // 不须要登录            }        },          { // 须要登录            "path": "pages/my/my",            "name": "login",            "desc": "我的"        }          //...  ]