Vue-router has three routing modes:
hash
: Uses the URL hash value for routing,Support for all routers
;history
: rely onHTML5 History API
And server configuration;abstract
: Supports all JS runtime environments, node.js server;
1.1. Route function: Map different paths to different views.
1.2 Basic use of routes:
<div id="app">
<h1>Hello kuishou!</h1>
<p>
<! --<router-link> is rendered as a '<a>' tag by default -->
<router-link to="/foo">Sleep Foo</router-link>
<router-link to="/bar">Knock on the bar code</router-link>
</p>
<! Components that match routes will be rendered here -->
<router-view></router-view>
</div>
Copy the code
import Vue from 'vue'
import VueRouter from 'vue-router'
// Register the route
Vue.use(VuerRouter)
// 1. Define components
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. Define the route
const routes = [
{ path: '/foo'.components: Foo },
{ path: '/bar'.components: Bar },
]
Copy the code
2,Route registration:
Use: When we execute Vue. Use, we execute this method and take the Vue object as the first parameter in the method.
3. Route installation:
The most important step in the vue-Router installation is to use the Vue.mixin to inject the beforeCreate and Destroyed hook functions into each component, define the private properties and initialize the route in the beforeCreateed.
// install.js
// Export _Vue from the source code. You can access Vue from anywhere in the source code
export let _Vue
export function install (Vue) {
// Check whether there is a register directive, return if install is executed multiple times
if (install.installed && _Vue === Vue) return
install.installed = true
// Use the underscore _Vue to keep the Vue
_Vue = Vue
const isDef = v= >v ! = =undefined
const registerInstance = (vm, callVal) = > {
let i = vm.$options._parentVnode
if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
i(vm, callVal)
}
}
// Mixin: extends mergeOptions to global options
Vue.mixin({
BeforeCreate = beforeCreate = beforeCreate = beforeCreate = beforeCreate = beforeCreate = beforeCreate = beforeCreate
beforeCreate () {
if (isDef(this.$options.router)) {
this._routerRoot = this
this._router = this.$options.router
this._router.init(this)
Vue.util.defineReactive(this.'_route'.this._router.history.current)
} else {
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
}
registerInstance(this.this)
},
destroyed () {
registerInstance(this)}})Copy the code
3, VueRouter object:
When we execute the new VueRouter, the beforeCreated hook function executes the router.init method,
constructor (options: RouterOptions = {}) {
this.app = null // Root Vue instance
this.apps = [] // Save Vue instances for all subcomponents
this.options = options // Save the incoming route configuration
this.beforeHooks = [] // Hook function
this.resolveHooks = [] // Hook function
this.afterHooks = [] // Hook function
// Routing matcher
this.matcher = createMatcher(options.routes || [], this)
// There are three modes of route creation: hash, History, and Abstract
let mode = options.mode || 'hash'
// If the route fails to be created, check whether the browser has a history.
this.fallback =
mode === 'history'&&! supportsPushState && options.fallback ! = =false
// The actual implementation instance of the routing history, if not, will be accessed using hSAH
if (this.fallback) {
mode = 'hash'
}
if(! inBrowser) { mode ='abstract'
}
this.mode = mode
switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base)
break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback)
break
case 'abstract':
this.history = new AbstractHistory(this, options.base)
break
default:
if(process.env.NODE_ENV ! = ='production') {
assert(false.`invalid mode: ${mode}`)}}}Copy the code
4, the Matcher
A routing matcher, primarily through the matcher and match methods, matches a path to a Router.
- 4.1,
createRouteMap
The function is the user’sThe routing configurationConvert to oneRoute mapping table.
export function createRouteMap (
routes: Array<RouteConfig>, oldPathList? :Array<string>, // This parameter is optionaloldPathMap? : Dictionary<RouteRecord>,// This parameter is optionaloldNameMap? : Dictionary<RouteRecord>,// This parameter is optionalparentRoute? : RouteRecord) :{
pathList: Array<string>,
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>
} {
// The path list is used to control the path matching priority
const pathList: Array<string> = oldPathList || []
// $flow-disable-line
const pathMap: Dictionary<RouteRecord> = oldPathMap || Object.create(null)
// $flow-disable-line
const nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null)
// Iterate over the routing array
routes.forEach(route= > {
// Successful traversal · Got each routing object
addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)
})
Copy the code
- 4.1 Initialization logic for createMatcher
““const {pathList, pathMap, nameMap} = createRouteMap(routes) ‘ ‘is used to create a mapping table.
// Iterate over the routing array
routes.forEach(route= > {
// Successful traversal · Got each routing object
addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)
})
Copy the code
- 4.3 Match Matching process
** Calculate a new path based on the raw and current path currentRoute and return it.
The match method takes three arguments: raw (Location object), currentRoute (current path), and redirectedFrom (related to redirection).
function match (
raw: RawLocation, // URL string, which can also be a Location objectcurrentRoute? : Route,// Router type: indicates the current pathredirectedFrom? : Location// Related to redirection
) :Route {
// Calculate the new location based on raw, current
const location = normalizeLocation(raw, currentRoute, false, router)
const { name } = location
// If current is passed with a name attribute
if (name) {
// Record is matched by nameMap
const record = nameMap[name]
if(process.env.NODE_ENV ! = ='production') {
warn(record, `Route with name '${name}' does not exist`)}// If the record does not exist, the match fails!
if(! record)return _createRoute(null, location)
const paramNames = record.regex.keys
.filter(key= >! key.optional) .map(key= > key.name)
if (typeoflocation.params ! = ='object') {
location.params = {}
}
if (currentRoute && typeof currentRoute.params === 'object') {
for (const key in currentRoute.params) {
if(! (keyin location.params) && paramNames.indexOf(key) > -1) {
location.params[key] = currentRoute.params[key]
}
}
}
location.path = fillParams(record.path, location.params, `named route "${name}"`)
return _createRoute(record, location, redirectedFrom)
} else if (location.path) {
location.params = {}
for (let i = 0; i < pathList.length; i++) {
const path = pathList[i]
const record = pathMap[path]
if (matchRoute(record.regex, location.path, location.params)) {
return _createRoute(record, location, redirectedFrom)
}
}
}
// no match
return _createRoute(null, location)
}
Copy the code
5. Switch paths
A series of hook functions that are executed when a path switch occurs.
-
5.1 Execution process of navigation Guard
In Vue project, after navigation is triggered, the deactivated component (defector) starts calling beforeRouteLeave, the global guard (elder) beforeEach, and the guards within the component (third) reuse component beforeRouterUpdate are triggered step by step; Route guard starts parsing asynchronous routing components after calling beforeEnter in route configuration. BeforeRouteEnter is called on the active target component (enemy). The global guard beforeResolve detects that the target component (enemy) is activated (defeated), finds the navigation to jump to in router.js, and is confirmed. The afterEach hook is called, and the DOM update is triggered. The route guard calls the callback function beforeRouteEnter passed to next.
// Globalguard router.beforeeach ((to, from, next)=>{// Check whether the route is logged in before entering, if not jump to the loggedview component if(to.name! = 'Login' && ! IsAuthenticated) next({name: 'Login' // else}) else {next()}})Copy the code
Reference: www.jianshu.com/p/60da87d4e…
Official document: Vue-router
The guard identifies three keys to the route:
To: indicates the route to be entered
From: Indicates the route to be left
Next: Make the next hook in the pipeline
Interview question: What are some ways to pass data to a routing component?
1. Pass through params
// Params cannot be used with path
router.push({ path: './details'.parmas: { id: '001'}})// -> Go to details
Copy the code
2. Pass through query
this.$router.push({ path: '/details/001'.query: { kind: "car" }})
Copy the code
3. Pass by hash
this.$touter.push({ path: './details001'.hash: '#car'})
Copy the code
.
Reference: Vue Routing components pass parameters in eight ways