乐趣区

关于uniapp:unisimplerouter使用vuerouter管理uniapp路由

笔记中的内容仅实用于 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.js
const 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.js
import {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.js

import 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.js
import 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.js
router.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": "我的"
        }
          //...
  ]
退出移动版