This is the 24th day of my participation in the August Text Challenge.More challenges in August


One, foreword

In the previous part, the implementation of view update when routing changes was introduced, mainly involving the following contents:

  • Update the matching result of the current route.
  • Reregulation before routing update;
  • Responsive implementation of routing;

$route, $router, and router-link


two$route$routerThe implementation of the

1. Review

[VueRouter source code learning] chapter 2 – Routing configuration and use, introduced in:

When a Router plug-in is registered with vue. use, two global components are registered with Vue: router-link and router-view; At the same time, the instance is provided with two stereotype attributes: $router and $route;Copy the code
  • $route: contains routing attributes. For example, name, hash, and meta.
  • $router: contains routing-related methods; History API (push, Replace, go);

2. Define the prototype method$route

Add $route attribute to Vue prototype, attribute value is the current matching routing object;

// install.js

 /** * Add $route attribute to Vue prototype -> current object * $route: contains routing attribute */
  Object.defineProperty(Vue.prototype, '$route', {
    get() {
      // this points to the current instance; _routerRoot is available on all instances;
      // So this._routerroot. _route is the _router on the root instance
      // That is: reactive data defined when processing the root instance -> this.current object
      return this._routerRoot._route; // Contains route attributes such as PATH and matched}})Copy the code

3. Define the prototype approach$router

Add the $Router attribute to the Vue prototype with the value of the current router instance;

// install.js

  /** * Add $router to the Vue prototype -> Router instance * $router: contains routing-related methods */
  Object.defineProperty(Vue.prototype, '$router', {
    get() {
      // this._routerroot. _router is the current router instance;
      // The router instance contains methods like matcher, push, go, repace, etc.
      return this._routerRoot._router; }});Copy the code

Vue-router Official document: Routing object & Routing object properties


Three,<router-link>Component implementation

1. Create a Link component object

Create a Link component object in the vue-router component directory and simulate the return of a tag:

// vue-router/components/link.js

export default {
  name:'routerLink'.render(){
    return <a></a>}}Copy the code

When registering global components in the Install phase, import and use Link component objects:

// install.js

import Link from './components/link';
// Register the Vue global component
Vue.component('router-link', Link);
Copy the code

2,<router-link>Component functions

  • Each click<router-link>Component, the hash value will be switched.
  • <router-link>Components can receive external parameters;
  • <router-link>The content returned after component rendering includes: element label + click jump event + slot, etc.;

3,<router-link>Component implementation

  • Receiving external parameter props; Contains: target path to and tag name tag.
  • Jump method: handler; Push method under the current routing instance;
  • Render function render method, JSX template;
// vue-router/components/link.js

export default {
  // Component name
  name: 'routerLink'.// Receive attributes passed in from outside
  props: {
    to: { // Target path
      type: String.required: true
    },
    tag: {  // Label name, default a
      type: String.default: 'a'}},methods: {
    handler(to) {
      // Route jump: internal call history.push
      this.$router.push(to); }},render() {
    let { tag, to } = this;
    // JSX: tag + click jump event + slot
    return <tag onClick={this.handler.bind(this, to)} >{this.$slots.default}</tag>}}Copy the code

4,this.$router.pushMethod implementation

This.$router.push: this.$router.push: this.

index.js

class VueRouter {
    push(to) {
        this.history.push(to); // Subclass corresponding push implementation}}Copy the code

Note: History in the router instance is a subclass of the current routing mode, so the push method is also a subclass of push.

5,this.history.pushMethod implementation

Implement the push method in the HashHistory subclass:

// history/HashHistory.js

class HashHistory extends History {
  push(location) {
    // Jump to the path and update the hash value after the jump is complete;
    // transitionTo internal check: the hash value changes will jump again, but the current attribute will not be updated;
    this.transitionTo(location, () = > {
      window.location.hash = location;// Update the hash value}}})Copy the code

TransitionTo jumps when hash changes. Internal implementation of transitionTo:

// history/HashHistory.js

  /** * 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) {
    // Route matching according to the path; Route: indicates the current matching result
    let route = this.router.match(location);
    // Duplicate check: If the two paths are the same and the route matching results are the same, no operation is required
    if (location == this.current.path && route.matched.length == this.current.matched.length) { // Prevent duplicate jumps
      return
    }
    // Update current with the current route and perform other callbacks
    this.updateRoute(route);
    onComplete && onComplete();
  }
Copy the code

Perform a route match based on the current path, check before update, update current to match the route object for the latest time, and run window.location.hash = location to update hash.

6. Update the view…

After clicking the

component, the path will be switched, but the page is not rendered, so the

component is needed.


Four, the end

This article introduces the implementation of $route, $router and router-link components.

  • Define the prototype method$route$router;
  • <router-link>Component functionality and implementation;

Next, the implementation of the

component;