vue-router的实现

65 阅读1分钟

vue-router的使用

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',
        component: () => import(/*webpackChunkName: 'about'*/'./views/About.vue'),
        childrend:[
            
        ]
    }
]

const router = new VueRouter({
    routes,
});

const app = new Vue({
    el: '#app',
    router,
})

vue-router的实现

let Vue;

class VueRouter {
    constructor(options){
        this.$options = options;
        
        const initial = window.location.hash.slice(1) || '/';
       // this.current变成响应式数据 Vue.util.defineReactive(this,'current',initial);
       // 缓存path和route的映射关系
       this.routeMap = {};
       this.$options.routes.forEach(route => {
           this.routeMap[route.path] = route;
       })
        // 监听url变化
 window.addEventListener('hashchange',()=>{
            this.current = window.location.hash.slice(1) || '/'
        })
        
    }
}
// 1.插件,实现install方法
VueRouter.install = function(_Vue){
    // 保存Vue构造函数
    Vue = _Vue;
    // 2.挂载$router到Vue原型
    // Vue.prototye.$router = 这种方式拿不到router实例
    // 利用全局混入,延后执行方式
    Vue.mixin({
        beforeCreate(){
            // this是组件实例
            if(this.$options.router){
                Vue.prototype.$router = this.$options.router;
            }
        }
    })
    
    // 3.声明2个全局组件router-view,router-link
    Vue.component('router-link',{
        props:{
            to:{
                type: String,
                required: true
            },
        },
        render(h){
            // jsx
            return <a href={`#${this.to}`}>{this.$slots.default}</a>
            // h函数
            return h('a',
                {
                    attrs:{
                        href: `#${this.to}`
                    }
                },
                this.$slots.default
            )
        }
    })
    
    Vue.component('router-view',{
        render(h){
            const {routeMap, current} = this.$router;
            const component = routeMap[current] || null;
            return h(component);
        }
    })
       
};

export default VueRouter;