This is the 22nd day of my participation in the August Wen Challenge.More challenges in August


One, foreword

In the previous part, the design and initialization of two routing modes were introduced, mainly involving the following contents:

  • Create two routing pattern classes;
  • The design of parent and subclass inheritance methods;
  • Route initialization init processing logic;

This article introduces the implementation of route matching.


Two, connecting the preceding and the following

1. Review

  • When vue. use is executed to install the plug-in, the exported Router instance is mixed with vue. mixin to all components.
  • Save the Router instance on the root component to_routerRootSo that all components can obtain the root component from the parent, that is, they can access the same Router instance.
  • When VueRouter is instantiated, the route configuration is flattened by createMatcher.
  • In the routing matcher, two core methods of the routing plug-in are created: match and addRoutes.
  • History was created in VueRouter to store the implementation of subclass logic in different schemas;
  • During route initialization, route jump transitionTo is executed by default and route change listeners are bound at this time. After that, when the Hash changes again, the switch continues.

2. Introduction to this article

Therefore, the next step is to obtain the route matching result according to the current path in the jump method transitionTo.


Third, analysis of route matching

The route configuration is flattened using the route matcher. For example:

{'/': Record1, '/user': Record2, '/user/info': Record3 }
Copy the code

Next, the route is matched. If the access path is: /user/info, the result of the route match is two: /user/info

// User /info can be matched only after /user is matched.
matches:[Record2, Record3]
Copy the code

Therefore, a path may correspond to multiple matching rules at the same time.

Note: Multiple records matched in matches are used for component rendering in

;


Fourth, the realization of route matching

1. Routes are matched for the first time

When the page is loaded, the route initialization process enters the init method, which triggers a route jump transitionTo by default. In this case, a route matching operation is required, that is, a route matching operation is performed based on the current page path location to the matcher on the Router instance.

// history/base.js

/** * Routing base class */
class History {
  constructor(router) {
    this.router = router;
  }

  /** * Route jump methods: * Need to know from and to every jump * responsive data: View refreshes when path changes *@param {*}} location 
   * @param {*} onComplete 
   */
  transitionTo(location, onComplete) {
    // Match routes based on paths
    let route = this.router.match(location); onComplete && onComplete(); }}export { History }
Copy the code

2. Implementation of router. Match

Add the match method to the VueRouter class to provide a route jump call:

/** * The VueRouter class uses the match method to provide access to the matcher, not directly to the matcher@param {*} A location path *@returns Match result array */
match(location) {
    // createMatcher.match
    return this.matcher.match(location);
}
Copy the code

Note: According to the design principle of class encapsulation, in the History class method, the instance attribute matcher of VueRouter class cannot be accessed directly.


3. Implementation of matcher. Match

Implementation of match method in createMatcher:

import createRouteMap from "./create-route-map"
import { createRoute } from './history/base'

/** * Route matcher * Route configuration flattening * Core methods: addRoutes, match *@param {*} routes 
 * @returns * /
export default function createMatcher(routes) {

    let { pathMap } = createRouteMap(routes); // Route configuration flattening

    function addRoutes(routes) {
        createRouteMap(routes, pathMap);
    }

    function match(location) {
        // Get the routing record
        let record = pathMap[location]; // A path may have multiple records
        // The match is successful
        if (record) {
            return createRoute(record, {
                path: location
            })
        }
        // No match was found
        return createRoute(null, {
            path: location
        })
    }

    return {
        addRoutes, // Add a route
        match // Used to match paths}}Copy the code

4, createRoute implementation

Let Record = pathMap[location] Matches a routing record;

The routing records need to be split and matched layer by layer. CreateRoute is used to obtain an array of matching records:

// history/base.js

/** * Layer by layer through the route record to match *@param {*} Record Indicates the route record *@param {*} A location path *@returns All matching results after matching layer by layer */
export function createRoute(record, location) {
  let res = []; //[/about /about/a] 
  if (record) {
    while(record) { res.unshift(record); record = record.parent; }}return {
    ...location,
    matched: res
  }
}

class History {
  constructor(router) {
    this.router = router;
    // {'/': Record1, '/user': Record2, '/user/info': Record3 }
    this.current = createRoute(null, {
      path: '/'
    });
  }

  /** * Route jump methods: * Need to know from and to every jump * responsive data: View refreshes when path changes *@param {*}} location 
   * @param {*} onComplete 
   */
  transitionTo(location, onComplete) {
    // Match routes based on paths
    let route = this.router.match(location); onComplete && onComplete(); }}export { History }
Copy the code

Five, the end

This article introduces the implementation of route matching, including the following points:

  • Analysis of routing matching;
  • Router match, matcher. Match, createRoute;

Next, TBD