“This is the 11th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

background

In a previous article, how does vue-Router do page switching? Router4 Matcher is an important component of router4. Router4 Matcher is a component of Router4. Router4 Matcher is an important component of Router4. Vue-router and history form the core of vue-Router. Let’s go back to creating a router in Vue-Router4

const router = VueRouter.createRouter({
  history: createWebHistory(),
  routes,
});
Copy the code

It also implies that history and routes are important. Without further ado, this article will introduce matcher in Vue-Router4

Note: The matcher analysis and source code in this article correspond to vuE-Router4, which is vuE3 version of the router

{route: “/”, Redirect: “/test”} {route: {path: “/”, Redirect: “/test”}[route,route,...]

addRoute

When creating a Router instance, the Options. routers will be carried from the createRouter to the createRouterMatcher and the matcher will be initialized. The code is as follows

// code
const routes = [
  { path: "/".component: Home },
  { path: "/about".component: About },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});
// source code
function createRouter(options: RouterOptions) :Router {
  / / options. Routes routes namely = [{path: "/",...}, {path: "/ about...}]
  const matcher = createRouterMatcher(options.routes, options);
  // ...
}
Copy the code

The addRoute in the createRouterMatcher will be one route by one, and the route will be parsed. droute in the createRouterMatcher will be one route by one. The routes passed in at the beginning will not be the routes actually used in Vue-Router4. The matcher section will handle them further, such as aliases

function createRouterMatcher(routes: RouteRecordRaw[], globalOptions: PathParserOptions) :RouterMatcher {
  // ...
  // Add initialized routes, or encapsulated routes
  routes.forEach((route) = > addRoute(route));
  // ...
}
Copy the code

Here are five things That addRoute actually did inside the createRouterMatcher

  1. Initial repairs to routes-Normalize
  2. Merge option
  3. Process aliases -alia
  4. Repaired the routes for the second time
  5. Returns true –routes

Next, we will introduce the above points

Initial repairs to routes-Normalize

Router4 router4 router4 router4 router4 Router4 Router4 Router4 Router4

Matcher entry in Normalize is a factory function (small details), but remember that VUE – Router4 is written in typescript and its return value is defined. Let’s look at this function

function normalizeRouteRecord(record: RouteRecordRaw) :RouteRecordNormalized {
  return {
    path: record.path,
    redirect: record.redirect,
    // ...
  };
}
Copy the code

The factory function returns a normalized key to the RouteRecordNormalized interface. This function returns a normalized object to the RouteRecordNormalized interface. RouteRecordNormalized(Path, redirect, etc.) returns a normalized value to RouteRecordNormalized(Path, redirect…). The constructor is created if the RouteRecordNormalized is a Class.

RouteRecordNormalized returns a formatted copy of the route. RouteRecordNormalized returns a formatted copy of the route

// code
const routes = [{ path: "/".component: Home }];
// source code
// route: RouteRecordRaw to route: RouteRecordNormalized
Copy the code

So what does this factory function do with the route that we passed in at the beginning? Then there’s the process

The process

RouteRecordRaw to RouteRecordNormalized to Start date with a string. RouteRecordRaw to RouteRecordNormalized to Start Date with a string. RouteRecordRaw to RouteRecordNormalized to Start Date with string

// code
const route = { path: "/".component: Home };
// corresponding to the following
const route = {
  path: "/".redirect: undefined.name: undefined.meta: undefined.alias: undefined.beforeEnter: undefined.props: undefined.children: undefined};// Source code: normalizeRouteRecord Processing
const route = {
  path: "/".redirect: undefined.name: undefined.meta: {},
  beforeEnter: undefined.props: undefined.children: [].// Add a new section
  aliasOf: undefined.instances: {},
  leaveGuards: new Set(),
  updateGuards: new Set(),
  enterCallbacks: {},
  components: undefined};Copy the code

This process is an important point is the props processing, here can look at the vue-router-apI-props reference, the documentation of the requirements can be represented in the source code, a brief look at the source code

function normalizeRecordProps(
  record: RouteRecordRaw
) :Record<string._RouteRecordProps> {
  const propsObject = {} as Record<string, _RouteRecordProps>;
  // The redirected route will not have props, so its props value should be false
  const props =
    (record as Exclude<RouteRecordRaw, RouteRecordRedirect>).props || false;
  if ("component" in record) {
    propsObject.default = props;
  } else {
    // Minor details: The props function mode can be applied to the corresponding named view component
    for (const name in record.components)
      propsObject[name] = typeof props === "boolean" ? props : props[name];
  }

  return propsObject;
}
Copy the code

The above source code is really just three modes for props

  1. The Boolean model
  2. Object pattern
  3. The function mode

[root_props] [props] [root_props] [root_props] [root_props] [root_props] [root_props] [root_props] After all, vue-Router4 has very little constraint on the value of route

{path: “/”, Redirect: “/test”}

// code
{ path: "/".Redirect: "/test" }
// source code
{ path: "/".Redirect: "/test".props: false }
Copy the code

Object mode and Boolean mode are handled this way

if ('component' in record) {
  propsObject.default = props
Copy the code

The propsobject. default = props, because it’s compatible with named views, so whether you start route with named view mode or not, After processing, props must have propsobject. default = XXX

Not to mention naming the view, let’s see what happens when we process it. Okay

for (const name in record.components)
  propsObject[name] = typeof props === "boolean" ? props : props[name];
Copy the code
// code
const props = { default: true.other: true }
// source code
const propsObject = { default: true.other: true }
Copy the code

Minor details not found in vue-Router documentation

When route is named view mode, if props is Boolean is actually applied to each component, as in the example below

const routes = [
  {
    path: '/user/:id'.components: { default: User, sidebar: Sidebar },
    props: true}]// is equal to the following
const routes = [
  {
    path: '/user/:id'.components: { default: User, sidebar: Sidebar },
    props: { default: true.sidebar: true}}]Copy the code

conclusion

The matcher vue – the router

  1. CreateRouterMatcher – Creates and initializes a matcher
  2. AddRoute – Initializes the route passed in
  3. NormalizeRouteRecord – Encapsulates the incoming routeupgrade, corresponding to the API document RouteRecordNormalized
  4. NormalizeRecordProps – Processing props, corresponding to the route reference section of the document

Let’s return to the theme at the end. If you want to find components, you’re done. So if that’s what you’re looking for, you can end up with the matcher by the addRoute, and then you’ve got a routing map, and the rest is done. But the article is actually going into more detail (yes, details weird). Finding the right route is a success, and that route handling is part of it

Router4 normalize router4 router4 normalize Router4 router4 Router4 Normalize Router4 router4 Router4 Router4 Router4 Normalize Router4 Router4 Router4 Router4 Router4 You can see several source code analysis post later (pay attention to see subsequent updates)

  1. How does vue-Router find vUE components to render? Vue-router Matcher resolves (2) – No write – handles aliases
  2. How does vue-Router find vUE components to render? Route-router Matcher (