Use of routes

  1. Initialize the
  2. Defining a Routing Group
  3. Load the route to the VUE
    import VueRouter from './router.js' // Define the routing source
    
    Vue.use(VueRouter);
    
    const routes = [
      {
        path: '/'.name: 'Home'.component: Home,
      },
      {
        path: '/about'.name: 'About'.component: () = > import(/* webpackChunkName: "about" */ '.. /views/About.vue'),
        children: [{path: '/about/info'.name: 'homeAbout'.component: { render: function (createElement) {
              return createElement('h3'.'info page'}}}]}]const router = new VueRouter({
      routes
    })
    
    // VUE code mount, need to create a home page import App component, basically used vUE development should understand.
    new Vue({
      router,
      render: h= > h(App)
    }).$mount('#app')
    
Copy the code

Routing source

  1. Routing points require a router-link component and a router-View component
  2. Router-link supports router-link. Router-view displays components in the corresponding path and refreshes the page.
  3. Monitor browser path changes, find matching components, refresh the page, and support nested routines
    import Link from "./router-link.js";
    import View from "./router-view.js";
    
    let Vue;
    
    class VueRouter {
      constructor(optins) {
        this.$options = optins; // Save options

        // Mixins are used here because vue.use (VueRouter) comes before new VueRouter, so there is no optins when install executes.
        // We can use a generic mixin beforeCreate life cycle to initialize the assign option once.
        Vue.mixin({
          beforeCreate () {
            if (this.$options.router) { // Only the root component has the $options.router parameter to avoid repeated assignments
              Vue.prototype.$router = this.$options.router; // Mount an instance of VueRouter on the Vue prototype for use in the component.}}})this.currentPath = window.location.hash.slice(1) | |'/'; // Get the initial path after #
        Vue.util.defineReactive(this."routeMatched"[]);// Listen for the matching path, which requires the corresponding rendered component.
        this.setMatched(); // Set the component that matches the path

        // Listen for browser hash path changes to handle accordingly
        window.addEventListener("hashchange".this.onHashChange.bind(this)) // Bind the current scope to prevent loss

      }

      onHashChange() {
        this.currentPath = window.location.hash.slice(1); // Get the latest browser path
        this.routeMatched = []; // When the route path changes, it needs to be re-matched, so it needs to clear the previously matched components
        this.setMatched();
      }

      setMatched(routes) {
        routes = routes || this.$options.routes;
        for(const route of routes) {
          const { path } = route; 

          if (path === "/" && this.currentPath === "/") { // Determine the root route
            this.routeMatched.push(route);
            return;
          }

          // Add the component directly if the current browser path contains the route path
          if(path ! = ="/" && this.currentPath.indexOf(path) ! = = -1) {
            this.routeMatched.push(route);
            if (route.children) this.setMatched(route.children); // If there are child routes, continue matching until all components are populated in the routeMatched.
            return;
          }

        }
      }
    }
    
    VueRouter.install = (_Vue) = > { // Vue plug-ins need an install method to initialize when they are mounted

      Vue = _Vue; // Save the vue instance object, which is used in VueRouter

      // Register dom components with router-view and router-link
      Vue.component("router-link", Link);
      Vue.component("router-view", View);
    }
    
    export default VueRouter
    
Copy the code

To realize the router – the link

  1. Create an A tag that takes a to parameter
    export default {
      props: {
        to: { type: String.required: true}},render(h) { // Create a simple A tag jump component
        return h("a", 
          {
            attrs: { href: "#" + this.to }
          },
          [ this.$slots.default ]
        )
      }
    }
Copy the code

Implement the router – the view

  1. The core idea is to identify the current component as router-view and recursively find whether the parent component is router-view. If it is, it indicates that there is a nested routine currently. We need to return the corresponding component according to the layer of the current router-View.
    
    export default {
      render(h) {

        this.$vnode.data.routerView = true; // Mark the current component as routerView
        let depth = 0; // Mark the depth used for nested routines to return the matching components at what level
        let parent = this.$parent;

        while (parent) {
          // Check if the parent component is a routerView, if it is a depth increment, until the root component is traversed.
          const isRouterView = parent.$vnode && parent.$vnode.data.routerView;
          if (isRouterView) depth++;
          parent = parent.$parent;
        }

        let component = null;
        const route = this.$router.routeMatched[depth]; // Select the component of the current routerView level.
        if (route && route.component) component = route.component;

        returnh(component); }}Copy the code

Page using

  1. Home page
    <template>
      <div id="app">
        <div id="nav">
          <router-link to="/">Home</router-link> |
          <router-link to="/about">About</router-link>  |
          <router-link to="/about/info">/about/info</router-link>
        </div>
        <div class="view-content">
          <router-view></router-view>
        </div>
      </div>
    </template>
Copy the code

2. The subroute of about page

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <router-view></router-view>
      </div>
    </template>
Copy the code

conclusion

  1. The above code realizes the core idea of VUe-Router, which can help us better understand vue-Router and the principle of front-end routing.
  2. Vue-router source code there are more details and more function points, if you want to continue to understand the details of the students can go to vue-Router source code research.
  3. One last little question, every time the browser path changes, we are going to use setMatched to traverse the corresponding component, so how can we cache the result so that we can switch back to the used path again in the future, without having to traverse again?