一个简单的vue的路由实现
首先要确定我们要做的功能点
VueRouter是一个插件,要有install方法
要实现router-view和router-link两个组件
要监听url的变化,hash模式要监听hashchange事件,history模式要监听popstate事件
实现根据不同的路由变化显示不同的组件
1. 声明类
class SimpleVueRouter {}
2. 注册install方法,接收Vue类
SimpleVueRouter.install = function(_Vue) {
// Vue是js内部的变量,_Vue是真正的Vue类
Vue = _Vue;
}
3. 写SimpleVueRouter的构造函数,保存传进来的路由配置options,声明一个路由对应关系,声明一个Vue的实例对象用于响应式
class SimpleVueRouter {
constructor(options) {
this.$options = options;
this.routeMap = {};
this.app = new Vue({
data() {
return {
current: '/'
}
}
});
}
}
4. 在SimpleVueRouter类里新增init方法,在install方法里给Vue注册mixin,给Vue加上$router和执行init方法
为什么要使用mixins,因为我们需要把VueRouter的实例对象挂载在当前Vue的实例上,但是在Vue.use的时候,实例对象还没有生成,必须要在实例对象已经生成了才行,所以注册一个全局的mixin,便于初始化的时候挂载VueRouter实例
// 添加install方法,在Vue.use的时候会执行
SimpleVueRouter.install = function(_Vue) {
Vue = _Vue;
Vue.mixin({
beforeCreate() {
/**
* this是Vue的实例对象
* this.$options是new Vue()的时候传入的参数
* 只有main.js才会有router这个项,所以if只会进入一次
* */
if (this.$options.router) {
this.$router = this.$options.router;
this.$options.router.init();
}
}
});
}
5. 监听浏览器的hashChange和load方法事件,当监听到的时候,修改this.app.current
initEvent() {
// 监听浏览器的hashchange和load事件,使用bind改变this指向
window.addEventListener('hashchange', this.handleHashChange.bind(this));
window.addEventListener('load', this.handleHashChange.bind(this));
}
handleHashChange() {
// 获取#后面的部分赋值给app的current
this.app.current = location.hash.slice(1);
}
6. 注册路由对应关系
initRouteMap() {
this.$options.routes.forEach(item => {
this.routeMap[item.path] = item;
});
}
7. 注册s-router-link和s-router-view组件
registerComponents() {
// router-link默认展示a标签,用于点击跳转
Vue.component('s-router-link', {
props: {
to: String,
required: true,
},
render: function (h) {
return h('a', { attrs: { href: `#${this.to}` } }, this.$slots.default);
}
});
// router-view是一个容器,展示当前路由对应组件即可
Vue.component('s-router-view', {
render: h => {
// 此处使用箭头函数,为了让this指向当前router实例而不是vue实例
const com = this.routeMap[this.app.current].component;
return h(com)
}
});
}
8. 在init方法里分别初始化事件、路由和组件
init() {
this.initEvent();
this.initRouteMap();
this.registerComponents();
}
9. 使用方法
import SimpleVueRouter from './simple-vue-router';
import Vue from 'vue';
import Com1 from './components/com1';
import Com2 from './components/com2';
import Home from './components/home';
Vue.use(SimpleVueRouter);
export default new SimpleVueRouter({
routes: [{
path: '/',
component: Home
}, {
path: '/com1',
component: Com1
}, {
path: '/com2',
component: Com2
}]
});
com1
com2
整个思路流程就是,注册插件,监听浏览器的hash改变事件,当hash改变的时候,修改某个vue实例的某个属性,利用vue的响应式,使用到的地方也会改变,从而去更新router-view显示的地方
需要准备的知识包括:
- 如何注册Vue插件
- 如何注册组件
- Vue的mixin
- render函数的用法
本例只实现了使用hash的方式的实现简单的路由跳转和显示,其他方法读者有兴趣的话可以自己实现