美文网首页
手动实现简单Vue Router

手动实现简单Vue Router

作者: key君 | 来源:发表于2019-10-05 21:26 被阅读0次
如果用官方的router就安装

vue add router
然后选no 哈希模式

main.js

在main.js里先在vue根实例挂载我们的自定义路由实例

import router from './krouter'
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})
krouter.js

当Vue.use()执行的时候,会走KVueRouter的install方法,在vue的构造函数里面混入我们自定义路由实例,并执行了初始化方法,创建KVueRouter实例并传入配置对象

import Vue from 'vue'
import KVueRouter from './kvue-router'
import Home from './views/Home'
import About from './views/About'
Vue.use(KVueRouter)

export default new KVueRouter({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },{
        path: '/about',
        name: 'about',
        component: About
      }
  ]
})

kvue-router.js

构造函数保存传入的配置对象
this.app保存了vue data实例,用来做vue的数据响应式
bindEvents函数:当url哈希值改变和第一次加载时,响应式改变当前url的哈希值
createRouteMap函数:遍历routes配置项数组把里面每一个路由对象作为value 每一个路由对象的path作为key保存在routeMap对象中。
initComponent函数:
创建了router-link组件,实际上a标签+插槽,用的是h函数
创建了router-view组件,获取到routeMap对象中当前路径的对应的组件,也是用h函数创建

let Vue;
//声明Router类
export default class KVueRouter{
    //构造函数 传入对象 
    constructor(options){
        //1 解析route配置 生成map
        //用属性保存一下变量
        this.$options = options;
        //声明一个空对象
        this.routeMap = {};

        //url响应化处理:只要url变化 用到url的组件就会render
        //只有把数据放在data里面就是响应式的
        this.app = new Vue({
            data : {
                current: '/'
            }
        })
    }

    //声明初始化函数
    init(){
        //1事件监听
        this.bindEvents();
        //2路由映射操作
        this.createRouteMap();
        //3组件声明和注册
        this.initComponent();
    }
    //监听hashchange
    bindEvents(){
        window.addEventListener('hashchange',this.onHashChange.bind(this))
        window.addEventListener('load',this.onHashChange.bind(this))
    }
    onHashChange(){
        //url井号后面就是hash
        //#/index 只拿井号后面的
        this.app.current = window.location.hash.slice('1') || '/'
    }
    //路由映射
    createRouteMap(){
        //循环遍历路由配置项
        this.$options.routes.forEach(item => {
            //key是path value是整个路由配置项对象
            this.routeMap[item.path] = item;
        })
    }

    initComponent(){
        Vue.component('router-link',{
            props: {
                to: String
            },
            render(h){
                //<a href={this.to}>{this.$slot.default}</a>
                //h(tag,data,children)
              return h('a',{attrs:{href: '#'+this.to}},[this.$slots.default]);  
            }
        })
        Vue.component('router-view',{
            render:(h) => {
                const component = this.routeMap[this.app.current].component;
              return h(component);  
            }
        })
    }
}

//实现插件
//插件接收vue构造函数
KVueRouter.install = function (_vue) {
    //是Vue的构造函数 用变量保存
    Vue = _vue;
    //在这一层的this会是谁呢

    //混入 进行挂载操作
    Vue.mixin({
        //传入一个生命周期函数
        beforeCreate(){
            //main.js根组件实例挂载了一次路由器的实例router
            //this就是vue实例 === 根组件实例
            if(this.$options.router){
                //为了拿路由器的实例
                Vue.prototype.$router = this.$options.router;
                //执行初始化
                this.$options.router.init();
            }
        }
    })
}
使用
     <nav>
        <router-link to="/">home</router-link>
        <router-link to="/about">about</router-link>
      </nav>
      <router-view></router-view>

相关文章

网友评论

      本文标题:手动实现简单Vue Router

      本文链接:https://www.haomeiwen.com/subject/jndcpctx.html