This is the seventh day of my participation in the First Challenge 2022. For details: First Challenge 2022.

When writing routing related code, after writing the relevant code of the page component, you can directly shuttle vue-Router, but how does vue-Router realize the switch between them?

I do not know if you have written JSP, I once briefly wrote JSP for a week, the process let me a little suffering, JSP engineering is not now we use webpack so good, such as hot update this open, JSP update is the need to restart the whole SpringBoot! It’s sad, but let’s just say that JSP implements page switching functions that actually write similar to vue-Router

<! -- A little bit of a named view -->
<jsp:include page="head.jsp"></jsp:include>
<html></html>
<jsp:include page="bottom.jsp"></jsp:include>
Copy the code
<router-view name="head"></router-view>
<router-view></router-view>
<router-view name="bottom"></router-view>
Copy the code

To switch between JSP pages, click on it and return to the.jsp file in the directory.

<router-link>

Router/SRC /RouterLink. Ts 184? Router/SRC /RouterLink

export const RouterLinkImpl = /*#__PURE__*/ defineComponent({
  // ...
  setup(props, { slots }) {
    const link = reactive(useLink(props));
    const{ options } = inject(routerKey)! ;// Style calculation
    // ...

    return () = > {
      const children = slots.default && slots.default(link);
      return props.custom
        ? children
        : h(
            "a",
            {
              "aria-current": link.isExactActive
                ? props.ariaCurrentValue
                : null.href: link.href,
              // this would override user added attrs but Vue will still add
              // the listener so we end up triggering both
              onClick: link.navigate,
              class: elClass.value, }, children ); }; }});Copy the code

returns a < A > that contains the URL to which you want to jump. This library uses the render function to render the component (h()) instead of






Because Vue-Router4 uses history mode, unlike hash mode, which doesn’t send a hash to the server if you change the URL with a #, history mode requires a redirect to be blocked otherwise it will jump to 404. Here’s an example




/ / the access complains HTTP: / / https://www.baidu.com/#xxx / / https://www.baidu.com/xxx this will notCopy the code

One more small detail, vue-Router4 is intercepted by default, because vue-Router4’s hash mode is not a real hash, and its underlying hash mode is history mode

<router-view>

Note note < the router – the view > is the key of page switching, but < the router – the view > source code is less than < the router – link >, 231 lines, but the core is the same, Router/SRC /RouterView.ts 43

export const RouterViewImpl = /*#__PURE__*/ defineComponent({
  setup(props, { attrs, slots }) {
    const injectedRoute = inject(routerViewLocationKey)!
    const routeToDisplay = computed(() = > props.route || injectedRoute.value)
    const depth = inject(viewDepthKey, 0)
    // Get the matching route
    const matchedRouteRef = computed<RouteLocationMatched | undefined> (() = > routeToDisplay.value.matched[depth]
    )

    // Pass the child router-view its own routing hierarchy
    provide(viewDepthKey, depth + 1)
    provide(matchedRouteKey, matchedRouteRef)
    provide(routerViewLocationKey, routeToDisplay)

    return () = > {
      const route = routeToDisplay.value
      const matchedRoute = matchedRouteRef.value
      const ViewComponent = matchedRoute && matchedRoute.components[props.name]
      const currentName = props.name

      if(! ViewComponent) {return normalizeSlot(slots.default, { Component: ViewComponent, route })
      }

      const component = h(
        ViewComponent,
        assign({}, routeProps, attrs, {
          onVnodeUnmounted,
          ref: viewRef,
        })
      )
    }
  },
})
Copy the code

Small details,

deeply caters to the nesting doll nature, establishes a set of provide/inject parent-child

information transfer rules, through the parent

information transfer, Using vue-Router4’s matcher to find the correct routing components, yes, the so-called page switch is a process of finding components, for each separate VUE components, matched to find components, yes, today’s main role is Matcher!


matcher

Matcher is actually the core of vue-Router. It has a special folder, Router/SRC /matcher. Through this matcher, vue-Router will find the actual routing component from each click of our routing navigation

Came to the router/SRC/router. Ts 356

export function createRouter(options: RouterOptions) :Router {
  const matcher = createRouterMatcher(options.routes, options)
  ...
}
Copy the code

And a little bit of official documentation

const Home = { template: "<div>Home</div>" };
const About = { template: "<div>About</div>" };

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

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

The purpose of createRouterMatcher() is to create a mapping table for the routes we define.

uses this mapping table to find and render the components

conclusion

Vue-router4 Switches pages

  1. Matcher builds the mapping table
  2. <router-link>intercept<a>Jump, passing information to the history listener
  3. <router-link>Find and render components in the mapping table based on the provide/ Inject information

This is my third article about vue-Router4. I have read the core source code of Vue-Router4, but I feel that people do not like reading the source code of vue-Router4. In fact, vue-Router4 is a library that we almost always use when writing vue projects. Git clone releases a bunch of errors for Vue-Router4, while Vue-Router4 does not. Vs-code also provides typescirpt analysis, which makes it easy to find the definition of a method in Vue-Router4, and the declaration of a variable (vS-Code doesn’t do a very good job of that, but I’ll use Webstorm to look at it some other time). So the hard part about looking at the source code is the determination to start