Update the content
- Configure the routing
- In previous versions, routes need to be manually configured. After the version is updated, routes are automatically configured
-
Adding global Hooks
-
Global hooks were left out for performance reasons
-
The corresponding hooks will be added after the update
-
(= &? And other special characters will not support route transmission parameters, you can handle
- encodeURIComponent
- decodeURIComponent
-
The new Router usage mode
Navigate: [‘navigateTo’, ‘switchTab’, ‘reLaunch’, ‘redirectTo’]
usage
// File directory pages/home/index.vueexport default { navigate: ['navigateTo'} // The name of the folder (home) is generated.export default { navigate: ['navigateTo'.'switchTab'// navigateTo (home) // switchTab (home) // navigateTo (home Name of the folder (swhOME) // Other values // reLaunch name is the name of the folder (relhome) // redirectTo Name is the name of the folder (redhome)Copy the code
this.$minRouter.push({// name here corresponds to the generated name value name above:'home'Params: {id: 1}}); // This is the type of page to pass the parameter.$minRouter.push('swhome') // Get the page parameter this.$parseURL() // Go back to page this.$minRouter.back(-1)Copy the code
File directory router/index.js in the project
Route interception can be set to use similarly to Vue global front hooks
-
Specific seegithub
Uni-app provides the routing function for page hopping, but we still found some inconvenient points in the process of using it, as shown in the following figure:
What are the problems with page jumps
- Bad page path management problem
- Why is it difficult to manage: changing the page path, or not having to find changes when subcontracting
- The way parameters are passed is not very friendly
- Why not: Need to manually concatenate parameter lists
- The parameter type is single and only string is supported
- Whether you pass string or number or Boolean, you get a string
- Parameters truncated when passing special characters (e.g. qr code information)
- The reason is that (=&?) cannot be included. And other special characters
Create a project
The following code
exportDefault {// home page index:'/pages/index/index.vue', // my page is my:'/pages/my/index.vue'
}Copy the code
It looks like this when you use it
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view>
<text class="title">{{title}}</text>
</view>
<button @click="openPage"</button> </view> </template> <script> import url from'.. /.. /router'
export default {
data() {
return {
title: 'index'}},onLoad() { },
methods: {
openPage () {
uni.navigateTo({
url: url.my
})
}
}
}
</script>Copy the code
Router.js is a hassle to import when using router.js
Let’s look at the second and third questions
Let’s look at an example
If you have a lot of parameters, this is really not a good way to operate. Can you separate out the parameter part and concatenate it to the URL?
Surprised to find that the number passed turned into a string, the parameter is not true
I’m not going to show you the fourth problem
So without further ado, I believe that you should also understand the problems, and let’s solve them.
First create a file (minrouter.js) directory structure as follows
The following code solves the first problem
It is no longer necessary to import the router.js file
import urlSet from './router';
function openPage (url) {
uni.navigateTo({
url: `${urlSet[url]}`})}export default openPageCopy the code
The main.js file is modified as follows
import Vue from 'vue'
import App from './App'/ / introduce MinRouter file import openPage from'./MinRouter'
Vue.config.productionTip = false
App.mpType = 'app'OpenPage = openPage const app = new Vue({... App }) app.$mount(a)Copy the code
use
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view>
<text class="title">{{title}}</text>
</view>
<button @click="toPage"</button> </view> </template> <script>export default {
data() {
return {
title: 'index'}},onLoad() { },
methods: {
toPage () {
global.openPage('my')
}
}
}
</script>Copy the code
Let’s deal with the second and third questions
The third problem is that if you want to pass a number, whatever you pass will become a string.
Is there a way to turn data into a string and still restore it to its original type?
Using JSON solves the above problem, and the second problem is well addressed
Try modifying the original code
import urlSet from './router';
function openPage (url, query) {
const queryStr = JSON.stringify(query)
uni.navigateTo({
url: `${urlSet[url]}? query=${queryStr}`})}export default openPageCopy the code
use
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view>
<text class="title">{{title}}</text>
</view>
<button @click="toPage"</button> </view></template><script>export default {
data() {
return {
title: 'index'}},onLoad() { },
methods: {
toPage () {
global.openPage('my', {id: 123})
}
}
}
</script>Copy the code
Let’s tackle the fourth problem
(= &? And other special characters in the URL above is special meaning, so we need to encode json string
import urlSet from './router'; function openPage (url, query) { const queryStr = encodeURIComponent(JSON.stringify(query)) uni.navigateTo({ url: `${urlSet[url]}? query=${queryStr}` })} export default openPageCopy the code
All the above problems have been solved, but the feeling is still not good. Could you package it into a Vue plug-in, similar to VueRouter
The answer is yes
Packaging molding MinRouter
Change the router.js file to the following
import MinRouter from './MinRouter'Const router = new MinRouter({routes: [{routes: [{//'pages/index/index',
name: 'index'
},
{
path: 'pages/my/index',
name: 'my'}]})export default routerCopy the code
Change the main.js file to the following
import Vue from 'vue'
import App from './App'/ / introduce MinThe Router file import MinRouter from './MinRouter'// Import router file import minRouter from'./router'
Vue.config.productionTip = falseVue. Use (MinRouter)
App.mpType = 'app'const app = new Vue({ ... App, minRouter }) app.$mount(a)Copy the code
The above code configuration already looks like VueRouter
Add the following code to the MinRouter file
const toString = Object.prototype.toStringfunction
isObject (value) {
return toString.call(value) === '[object Object]'
}
function isString (value) {
return toString.call(value) === '[object String]
'}
function isDefault (value) {
return value === void 0
}
function install (Vue) {
Vue.mixin({
beforeCreate: function () {
if(! isDefault(this.$options.minRouter)) {
Vue._minRouter = this.$options.minRouter
}
}
})
Object.defineProperty(Vue.prototype, '$minRouter', {
get: function () {
return Vue._minRouter._router
}
})
}
function MinRouter (options) {
if(! (this instanceof MinRouter)) {
throw Error("MinRouter is a constructor and should be called with the 'new' keyword.")
}
isDefault(options) && (options = {})
this.options = options
this._router = options.routes || []
}
MinRouter.install = install
export default MinRouterCopy the code
Let’s set the openPage parameters
Name: indicates the page to be jumped
Query: parameter used to jump to the page
OpenPage ({name: jump page, query: {id: 123}})Copy the code
The openPage function is as follows
function openPage (args) {
let {name, query = {}} = args
let queryStr = null, path
queryStr = encodeURIComponent(JSON.stringify(query))
this.$minRouter.forEach(item => {
if (item.name === name) {
path = item.path
}
})
return new Promise((resolve, reject) => {
uni.navigateTo({
url: `/${path}? query=${queryStr}`,
success: resolve,
fail: reject
})
})
}Copy the code
this.$minRouterThe code above has been proxy, do not feel surprised, in fact, is the configuration of routes in the routeCopy the code
The above only route can only be navigateBack this way
You may want to add a parameter to control the route, but it is not easy. Since the openPage function cannot be added, can it be added to the route?
Let’s modify the router.js file
import MinRouter from './MinRouter'Const router = new MinRouter({routes: [{routes: [{//'pages/index/index', / /typeMust be the following values ['navigateTo'.'switchTab'.'reLaunch'.'redirectTo'] // Redirect (default redirect)type: 'navigateTo',
name: 'index'
},
{
path: 'pages/my/index',
name: 'my'}]})export default routerCopy the code
The openPage function is as follows
function openPage (args) {
let name, query = {}, queryStr = null, path, type
switch (true) {
case isObject(args):
({name, query = {}} = args)
break
case isString(args):
name = args
break
default:
throw new Error('Parameter must be an object or a string')}if (isObject(query)) {
queryStr = encodeURIComponent(JSON.stringify(query))
} else {
throw new Error('Query data must be Object')
}
this.$minRouter.forEach(item => {
if (item.name === name) {
path = item.path
type = item.type || 'navigateTo'}})if(! ['navigateTo'.'switchTab'.'reLaunch'.'redirectTo'].includes(type)) {
throw new Error(`name:${name}The inside of thetypeMust be the following values ['navigateTo'.'switchTab'.'reLaunch'.'redirectTo']`)
}
return new Promise((resolve, reject) => {
uni[type]({
url: `/${path}? query=${queryStr}`,
success: resolve,
fail: reject
})
})
}Copy the code
How to parse routing parameters
The following functions parse the route parameters
function parseURL () {
const query = this.$root.$mp.query.query
if (query) {
return JSON.parse(decodeURIComponent(query))
} else {
return{}}}Copy the code
Here is the complete MinRouter code
const toString = Object.prototype.toString
function isObject (value) {
return toString.call(value) === '[object Object]'
}
function isString (value) {
return toString.call(value) === '[object String]'
}
function isDefault (value) {
return value === void 0
}
function openPage (args) {
let name, query = {}, queryStr = null, path, type, isName = false
switch (true) {
case isObject(args):
({name, query = {}} = args)
break
case isString(args):
name = args
break
default:
throw new Error('Parameter must be an object or a string')}if (isObject(query)) {
queryStr = encodeURIComponent(JSON.stringify(query))
} else {
throw new Error('Query data must be Object')
}
this.$minRouter.forEach(item => {
if (item.name === name) {
path = item.path
type = item.type || 'navigateTo'
isName = true}})if(! IsName) {throw new Error(' No${name}Page `)}if(! ['navigateTo'.'switchTab'.'reLaunch'.'redirectTo'].includes(type)) {
throw new Error(`name:${name}The inside of thetypeMust be the following values ['navigateTo'.'switchTab'.'reLaunch'.'redirectTo']`)
}
return new Promise((resolve, reject) => {
uni[type]({
url: `/${path}? query=${queryStr}`,
success: resolve,
fail: reject
})
})
}
function parseURL () {
const query = this.$root.$mp.query.query
if (query) {
return JSON.parse(decodeURIComponent(query))
} else {
return{}}}function install (Vue) {
Vue.mixin({
beforeCreate: function () {
if(! isDefault(this.$options.minRouter)) {
Vue._minRouter = this.$options.minRouter
}
}
})
Object.defineProperty(Vue.prototype, '$minRouter', {
get: function () {
return Vue._minRouter._router
}
})
Object.defineProperty(Vue.prototype, '$parseURL', {
get: function () {
return Vue._minRouter.parseURL
}
})
Object.defineProperty(Vue.prototype, '$openPage', {
get: function () {
return Vue._minRouter.openPage
}
})}
function MinRouter (options) {
if(! (this instanceof MinRouter)) {
throw Error("MinRouter is a constructor and should be called with the 'new' keyword.")
}
isDefault(options) && (options = {})
this.options = options
this._router = options.routes || []
}
MinRouter.install = install
MinRouter.prototype.openPage = openPage
MinRouter.prototype.parseURL = parseURL
export default MinRouterCopy the code
Use as follows
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view>
<text class="title">{{title}}</text>
</view>
<button @click="toPage"</button> </view> </template> <script>export default {
data() {
return {
title: 'index'}},onLoad() {// parse the route parameter console.log(this).$parseURL())
},
methods: {
toPage() {// skip to my page query is the argument passed this.$openPage({
name: 'my',
query: {id: 123}
})
}
}
}
</script>Copy the code
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view>
<text class="title">{{title}}</text>
</view>
<button @click="toPage"</button> </view> </template> <script>export default {
data() {
return {
title: 'my'}},onLoad() {// parse the route parameter console.log(this).$parseURL())
},
methods: {
toPage() {// skip to index page // No arguments can be abbreviated as this.$openPage('index')
}
}
}
</script>Copy the code