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
和 $router
The 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.push
Method 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.push
Method 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;