发布时间:2022-08-14 文章分类:编程知识 投稿人:王小丽 字号: 默认 | | 超大 打印
目录
    • uni-simple-router
  • 一、快速上手

    • 扩一:webpack插件之DefinePlugin
    • 扩二:uni-read-pages 如何获取pages.json中的路由
  • 二、H5模式

    • 2.1 路由配置
    • 2.2 完全使用vue-router开发 (H5端)
    • 2.3 H5 路由传参
    • 2.4 H5端路由捕获所有路由或404路由
    • 2.5 路由懒加载
  • 三、小程序模式
  • 四、路由跳转

    • 4.1 组件跳转
    • 4.2 编程式导航
  • 五、跨平台模式

    • 5.1 提前享用生命周期
    • 5.2 导航守卫
  • 六、路由守卫-模块化

    • 扩三、require.context用法
uni-simple-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端)
// 使用 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 路由懒加载
三、小程序模式
四、路由跳转
4.1 组件跳转
4.2 编程式导航
五、跨平台模式
5.1 提前享用生命周期
5.2 导航守卫
六、路由守卫-模块化
// 1⃣ 创建 router文件夹,模块化配置 文件结构
|+------------------------+|
| router                   |
| |+--------------------+| |
| | modules              | |
| | |+----------------+| | |
| | | home.js          | | |
| | | index.js         | | |
| | |+----------------+| | |
| |+--------------------+| |
| index.js                 |
|+------------------------+|
// home.js
const home = [
  {
    path: '/pages/home/index',
    name: 'home'
  }
]
export default home
// modules下的index.js是一个模块读取
// ① require.context(directory, useSubdirectories, regExp) 具体详情:如下扩三
const files = require.context('.',false,/.js$/)
const modules = []
files.keys().forEach(key => {
  if (key === './index.js') return
  const item = files(key).default
  modules.push(...item)
})
export default modules // 将所有模块的路由模块整合到一起, routes Array
// router下的index.js 路由守卫
import modules from './modules/index.js'
import Vue from 'vue'
import CreateRouter from 'uni-simple-router'
import store from '@/store/store.js'
Vue.use(CreateRouter)
//初始化
const router = new CreateRouter({
 APP: {
  holdTabbar: false //默认true
 },
 h5: {
  vueRouterDev: true, //完全使用vue-router开发 默认 false  
 },
 // 也可以 通过uni-read-pages来读取pages.json文件的路由表,配合vue.config.js
 // router: [...ROUTES] // ROUTES是通过webpack的defaultPlugin编译成全局变量,具体操作上文
 routes: [...modules] //路由表
});
//全局路由前置守卫
router.beforeEach((to, from, next) => {
 // 首先判断是否存在路由信息
 //不存在就先调用接口得到数据
})
// 全局路由后置守卫
router.afterEach((to, from) => {})
export default router;
扩三、require.context用法
// require.context(directory, useSubdirectories, regExp)
// directory: 表示检索的目录
// useSubdirectories: 表示是否检索子文件夹
// regExp: 匹配文件的正则表达式
// 返回值: resolve是一个函数,返回已解析请求的模块ID; keys是一个函数,它返回上下文模块可以处理的所有可能请求的数组;
// 使用场景:①用来组件内引入多个组件;②在main.js内引入大量公共组件;
// ①组件内引入多个组件 - webpack
const path = require('path')
const files = require.context('@/components/home', false, /\.vue$/) //值类型 ['./home.js', 'detail.js',...]
const modules = {}
files.keys().forEach(key => {
  const name = paths.basename(key, '.vue') // 去掉文件名的 .vue后缀
  modules[name] = files(key).default || files(key)
})
// modules { home: '{module样式路径}', detail: '{}', ...  }
export default { 
  	...,
  	data() { return {}}, 
    components: modules
}
// ②在main.js内引入大量公共组件
import Vue from 'vue'
// 引入自定义组件
const requireComponents = require.context('../views/components',true,'/\.vue/')
// 遍历出每个数组的路径
requireComponents.keys().forEach(fileName => {
  const reqCom = requireComponents(fileName)
  // 获取组件名
  const reqComName = reqCom.name || fileName.replace(/\.\/(.*)\.vue/, '$1')
  // 组件挂载
  Vue.components(reqComName, reqCom.default || reqCom)
})