vue-router 源码之实现一个简单的 vue-router

2020-06-13 10:48:02易采站长站整理


constructor (Vue, options) {
this.$options = options;
this.routeMap = {};
this.createRouteMap(this.$options);
}

// 路由映射表
createRouteMap (options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item.component;
});
}

options 之中,路由与组件的关系:


const routes = [
{ path: '/', component: Home },
{ path: '/book', component: Book },
{ path: '/movie', component: Movie }
];

生成的路由映射表:


this.routeMap = {
'/': Home,
'/book': Book,
'/movie': Movie
};

响应

我们需要 new 一个新的 Vue 实例,将当前路由 current 储存在其 data 之中,当修改了 current 时,router-view 就会自己去更新视图。


constructor (Vue, options) {
this.app = new Vue({
data: {
current: '#/'
}
});
}

// 获取当前 hash 串
getHash () {
return window.location.hash.slice(1) || '/';
}

// 设置当前路径
onHashChange () {
this.app.current = this.getHash();
}

只要在

 router-view 
里使用到了
this.app.current
,一旦更新它,便会更新。

注册组件

router-link 
实际上就是一个 <a> 标签,点击它便能触发
hashchange
router-view 
会实现一个 render 方法,将当前路由对应的组件取出,进行渲染。


constructor (Vue, options) {
this.initComponent(Vue);
}

// 注册组件
initComponent (Vue) {
Vue.component('router-link', {
props: {
to: String
},
template: '<a :href="to" rel="external nofollow" rel="external nofollow" ><slot></slot></a>'
});

const _this = this;
Vue.component('router-view', {
render (h) {
var component = _this.routeMap[_this.app.current];
return h(component);
}
});
}

完整代码

至此,一个简单的 vue-router 就出来了,全部代码是这样的:


class VueRouter {
constructor (Vue, options) {
this.$options = options;
this.routeMap = {};
this.app = new Vue({
data: {
current: '#/'
}
});

this.init();
this.createRouteMap(this.$options);
this.initComponent(Vue);
}

// 绑定事件
init () {