Vue-router has three routing modes:
  • hash: Uses the URL hash value for routing,Support for all routers;
  • history: rely onHTML5 History APIAnd 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,createRouteMapThe 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