快深夜了,简单写点东西,不然还真睡不着觉哒 ~ ~
写什么好呢?前些天看了下vue-router的源码结构,理解了下 router-view 和 router-link 的基本实现;所以简单写一个vue-router的小功能版本,实现基本的路由切换,就可以了;好吧,接下来我们开始吧 ~~
一、最终路由切换展示
二、使用方式
其使用方式与原生的使用方式几乎一致,也有部分不同,由于并非使用install()方法实现,所以引入的方法并不需要Vue.use()
1. 在main.js中引入
import router from '@/custom-router/router.js'
2. 在router.js中定义路由配置
import Vue from 'vue';
import Router from './router-script.js';
const Home = { template: '<div>首页的内容</div>' };
const Music = { template: '<div>音乐详情页</div>' };
const Movie = { template: '<div>电影详情页</div>' };
const routes = [
{ path: '/', component: Home },
{ path: '/music', component: Music },
{ path: '/movie', component: Movie }
];
const router = new Router(Vue,{
routes
})
export default router
三、核心代码实现
1. 定义一个 Router 类
export default class Router {
constructor (Vue, options) {
//...
}
//...
}
2. 初始化绑定onhashchange、onload事件
// 绑定事件
init () {
window.addEventListener('load', this.onHashChange.bind(this), false);
window.addEventListener('hashchange', this.onHashChange.bind(this), false);
}
// 获取当前 hash 串
getHash () {
return window.location.hash.slice(1) || '/';
}
// 设置当前路径
onHashChange () {
this.app.current = this.getHash();
}
3. 路由组件映射
// 路由映射表
createRouteMap (options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item.component;
});
}
4. 全局注册 router-link 组件、router-view组件
// 注册组件
initComponent (Vue) {
Vue.component('router-link', {
props: {
to: String
},
template: `<a :href="'#'+to"><slot></slot></a>`
});
const self = this;
Vue.component('router-view', {
render (h) {
var component = self.routeMap[self.app.current];
return h(component);
}
});
}
5. 获取当前router-view要渲染对应的组件结构
// 设置当前路径
onHashChange () {
this.app.current = this.getHash();
}
四、完整代码结构
export default class Router {
constructor (Vue, options) {
this.$options = options;
this.routeMap = {};
this.app = new Vue({
data: {
current: '/'
}
});
this.init();
this.createRouteMap(this.$options);
this.initComponent(Vue);
}
// 绑定事件
init () {
window.addEventListener('load', this.onHashChange.bind(this), false);
window.addEventListener('hashchange', this.onHashChange.bind(this), false);
}
// 路由映射表
createRouteMap (options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item.component;
});
}
// 注册组件
initComponent (Vue) {
Vue.component('router-link', {
props: {
to: String
},
template: `<a :href="'#'+to"><slot></slot></a>`
});
const self = this;
Vue.component('router-view', {
render (h) {
var component = self.routeMap[self.app.current];
return h(component);
}
});
}
// 获取当前 hash 串
getHash () {
return window.location.hash.slice(1) || '/';
}
// 设置当前路径
onHashChange () {
this.app.current = this.getHash();
}
}