Vue Router的手写实现方法实现

2020-06-16 06:50:38易采站长站整理

<script>
export default {
methods: {
goBack() {
console.log(this.$router);
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
}
}
}
</script>

<style lang="less" scoped>

</style>

上面的代码中,我们可以直接使用router-link和router-view这两个组件。它们是随着 Vue Router 一起引入的,作为全局组件使用。

这就是一个最简单的 Vue Router 的使用方式。我们下面就来看看,该如何自己实现上面的简单功能,做一个自己的 Vue Router。

一个简单的 Vue Router 实现

看了上面的这个过程,最简单的 Vue Router 应该包括以下实现步骤:

实现 Vue 规定的插件的写法,将我们自己的Vue Router 作为插件引入 Vue 系统中。

router功能一:解析传入的routes选项,以备调用
router功能二:监控URL变化(两种路由方式:history、hash)

实现两个全局组件:router-link和router-view

看看自定义的 Vue Router 的实现:


//FVueRouter.js

let Vue; //保存 Vue 构造函数的引用,与 Vue 深度绑定

class FVueRouter {
constructor(options){
this.$options = options;
//保存路由的路径与路由组件的对应关系
this.routerMap = {};

//当前的URL必须是响应式的,使用一个新的 Vue 实例来实现响应式功能
this.app = new Vue({
data: {current : "/"}
})
}

init(){
//监听路由事件
this.bindEvents();
//解析传入的routes
this.createRouterMap();
//全局组件的声明
this.initComponent();
}

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

onHashChange(){
this.app.current = window.location.hash.slice(1) || '/';
}

createRouterMap(){
this.$options.routes.forEach(route => {
this.routerMap[route.path] = route;
})
}

initComponent() {
// 形式:<router-link to="/"> 转换目标=> <a href="#/" rel="external nofollow" >xxx</a>
Vue.component("router-link", {
props: {
to: String,
},
render(h) {
// h(tag, data, children)
return h('a', {
attrs: {href: '#' + this.to}
}, [this.$slots.default])
},
});
// 获取path对应的Component将它渲染出来
Vue.component("router-view", {
render: (h) => {
//此处的this 能够正确指向 FVouter内部,是因为箭头函数
const Component = this.routerMap[this.app.current].component;
return h(Component)
}
})
}
}

// 所有的插件都需要实现install 方法,传入参数是Vue的构造函数