Introduction to the

Vue-router, as a core class library of vUE global bucket, has many clever ways to implement it. Do you really understand it?

Use a vue-router’s correct posture.

The simplest is to install a vue-Router plug-in through cli, which will automatically modify the code of our project and correctly use vue-Router. One command.

vue add router
Copy the code

Correct posture.

  1. Create a routing configuration file.
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '.. /views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/'.name: 'home'.component: Home
  },
  {
    path: '/about'.name: 'about'.// route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: (a)= > import(/* webpackChunkName: "about" */ '.. /views/About.vue')}]const router = new VueRouter({
  routes
})

export default router

Copy the code
  1. Root component, which mounts the router.
import Vue from 'vue'
import App from './App.vue'
import router from './router';

Vue.config.productionTip = false

new Vue({
  router,
  render: h= > h(App)
}).$mount('#app')

Copy the code
  1. Use router-link for navigation and router-view for placeholder.

Does it look easy? The answer is yes, because the above steps are automatically added when installing vue-Router.

Our question is?

  1. Vue.use(VueRouter), what is this line of code for? Why do we put it at the top? Can we put it at the back?
  2. At the entrance, why pass router? What is it for?
  3. Where are the router-link, router-View components defined? Why can we just use it?
  4. How are components rendered after routing changes?

Core vue – the router.

lib/x-vue-router.js

/** * - create a plugin * - vueRouter is a class that can create an instance * - $router to mount to the prototype of vue. * - Listen for hash changes and respond to router-link. Router-view has two global components */
let Vue;
class XVueRouter {
  constructor(options) {
    this.$options = options;

    // Save the mapping between path and component.
    this.routeMap = {};

    // Use vue for data responsiveness. Curren saves the current URL hash
    // Once the hash is changed, use onHashChange to change the current value of the corresponding router-view component
    // The render method is re-executed (i.e., the new component is re-rendered and the path switch is successful).
    this.vm = new Vue({
      data: {
        current: '/'}});this.onHashChange = this.onHashChange.bind(this);
  }

  init() {
    // hashchange
    this.bindEvents();

    // Initialize the key-value pairs of path and component
    this.initRouteMap();

    // Add router-link and router-view components.
    this.createGlobalComponent();
  }

  bindEvents() {
    window.addEventListener('hashchange'.this.onHashChange);
    window.addEventListener('load'.this.onHashChange);
  }

  initRouteMap() {
    this.$options.routes.forEach(m= > this.routeMap[m.path] = m.component);
  }

  onHashChange() {
    // #/about -> /about
    this.vm.current = window.location.hash.slice(1) | |'/';
  }

  createGlobalComponent() {
    Vue.component('router-link', {
      props: { to: { type: String.required: true } },
      render() {
        return <a href={` # ${this.to} `} >{this.$slots.default}</a>; }}); Vue.component('router-view', {
      render: h= > h(this.routeMap[this.vm.current]) }); }}/** * Create a new plug-in. Implement a static install method. */
XVueRouter.install = function (_Vue) {
  // When a plug-in is installed through the vue. use method, a Vue constructor is passed in.
  Vue = _Vue;

  // Call vue's mixin method in the component's beforeCreate life cycle
  // Initialize vueRouter.
  Vue.mixin({
    beforeCreate() {
      // This refers to the router instance of the component.
      if (this.$options.router) {
        // 1. Mount the $router to the prototype of the vue, so that it can be called directly from within the component.
        Vue.prototype.$router = this.$options.router;

        // initialize vueRouter.
        this.$options.router.init(); }}})}export default XVueRouter;
Copy the code

After reading these 80 lines of code, do you have the answers to these four questions?

code

demo