This is the first day of my participation in the August Challenge. For details, see:August is more challenging

In a single-page application, when the URL changes, the page cannot be refreshed but the content of the view will change

First, let’s talk about how to use the Vue-Router

  1. Use the Vue-router plug-in in the router-js file
     import Router from 'vue-router Vue.use(Router)Copy the code
  2. Create a router instance in the router.js file and export it
    export default newRouter({... })Copy the code
  3. Add the instance to the root instance in the main.js file
    import router from './router new Vue({ router, }).$mount("#app");Copy the code
  4. Add route view and route forward link in app.vue file
    <router-link to="/home"></router-link>
    <! -- Route exit -->
    <router-view></router-view>
    Copy the code
    this.$router.push('/')
    this.$router.push('/home')
    Copy the code

2 through the use of steps to think about a few problems, with these questions let’s do, questions solved will understand

  1. Vue. Use (Router) this is the Router that uses the Vue plugin.
  2. new Vue({ router, }).$mount(“#app”); Why put router instances in new Vue options
  3. Why can the two components be used directly
  4. This.router. push: this is a router instance that can be used in a Vue instance

3. Our needs

  1. The SPA page cannot be refreshed
    1. Hash corresponds to toggle the ==> hashChange event
    2. H5 History API to implement
  2. According to the URL to display the content to do
    1. Implement components router-view and router-link
    2. In response to data processing, my hash changes and should dynamically rerender the content of the page

4. According to the needs and questions we have to complete things

  1. Implement a plug-in as the mainline
    1. Implement VueRouter class
      • Processing router options
      • Monitor URL changes,hashChange
      • In response to this change, render the new content
    2. Implement the install method (all vue plug-ins must have the install method), and the time to invoke it is when vue.use is invoked
      • $router registers with the Vue instance
      • Implement router-view and router-link global components

5. Code implementation

let Vue;
class VueRouter {
    constructor(options){
        this.$options = options;
        this.$routerMap = {};
        // Make current responsive
        // How to do that? = = >
        // 1. New Vue()
        // 2. Use vue.util.definereactive ()
        // this.current = window.location.hash.slice(1) || '/'; 

        Vue.util.defineReactive(this.'current' ,window.location.hash.slice(1) | |'/')
        window.addEventListener('hashchange'.() = > {
            // The current is not responsive.
            // So component updates are not triggered (if not handled by vue.util.definereactive)
            this.current =  window.location.hash.slice(1)})// Store a routing table object so you don't need to iterate over it
         this.$options.routes.forEach(item= >{
            this.$routerMap[item.path] = item
        })
        
    }

}
VueRouter.install = function(_vue){
    // So vue-router is a strong reference to vue
    Vue = _vue;
    // $router is registered with Vue instance
    // But we can't get the Vue instance at this time, so we need to do the registration at some point ===> mixin Vue
   Vue.mixin({
        beforeCreate() {
            // This is the vue instance
            console.log(this)
            if(this.$options.router){ 
                // The root component instance will have the router passed in when the router is instantiated
                Vue.prototype.$router = this.$options.router;
                console.log(this.$options.router)
            }
        }
    })
    // // implements two global components, router-link and router-view
    Vue.component('router-link', {   
        props: {
            to: {
               type: String.require: true}},render(h){
            // this.$slots. Default is to download the router-link tag, such as the home page
           return h('a', {attrs: { href: The '#' + this.to }}, this.$slots.default)
        }
    }) 

    Vue.component('router-view', { 
        // The execution time of render
        // 1. Init initialization
        // 2. Execute when the value of the dependency changes
         
        render(h){
        // This component renders the corresponding component content configuration items according to the URL
        / / {
        // path: '/',
        // name: 'app',
        // component: Home
        // }
        #/home #/home #/home #/home #/home
            // Our current is now responsive
            }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
        // 2. How do we get the route configuration options?
            // this.$router.$routerMap is a route mapping table
        // 3. h(Home)
            console.log(this.$router.$options)
            console.log(this.$router.current)
            console.log(this.$router.$routerMap);
            let Component;
            Component = this.$router.$routerMap[this.$router.current].component
            return h(Component)
        }})

}
export default VueRouter
Copy the code

6. This is the simplest implementation of vue-Router (using hash).

7. There are still some questions and thoughts

1. What to do with nested routines if they are not supported, that is, if the configuration item has the children option, how to write the code. When creating a route configuration item, you can pass a property: mode:'history'. Why does Vue need to be passed in at install instead of importing it from within?Copy the code

Bottom line: a little bit of progress every day will always change from super ghost to super god