1、vue-router: Vue Router 是 Vue.js 官⽅的路由管理器。它和 Vue.js 的核⼼深度集成,让构建单⻚⾯应⽤变得易如反掌。
2、安装:
vue add routerh
核心步骤:
使⽤vue-router插件,router.js
import Router from 'vue-router'
Vue.use(Router)
创建Router实例,router.js
export default new Router({...})
在根组件上添加该实例,main.js
import router from './router'
new Vue({
router,
}).$mount("#app");
添加路由视图,App.vue
<router-view></router-view>
导航
<router-link to="/">Home</router-link> <router-link to="/about">About</router-link>
this.$router.push('/')
this.$router.push('/about')
3、源码实现思路:
单⻚⾯应⽤程序中,url发⽣变化时候,不能刷新,显示对应视图内容
4、应用场景:
spa ⻚⾯不能刷新:hash #/about ;History api /about
根据url显示对应的内容:router-view;数据响应式:current变量持有url地址,⼀旦变化,动态重新执⾏render
5、实现一个插件,满足以下内容:
实现VueRouter类
处理路由选项
监控url变化并进行相应
实现install⽅法
$router注册
两个全局组件
6、要点:
创建VueRouter类和install⽅法
let Vue; class VueRouter {
constructor(options) {
this.$options = options;
}
}VueRouter.install = function(_Vue) {Vue = _Vue;Vue.mixin({
beforeCreate() {
// 只有根组件拥有router选项
if (this.$options.router) {
// vm.$router
Vue.prototype.$router = this.$options.router;
}
}
});Vue.component('router-link', Link)
Vue.component('router-view', View)
};
export default VueRouter;
创建router-link
export default {
props: {
to: String,
required: true
},
render(h) {
// return <a href={'#'+this.to}>{this.$slots.default}</a>;
return h('a', {
attrs: {
href: '#' + this.to
}
}, [
this.$slots.default
])
}
}
创建router-view
export default {
render(h) {return h(null);
}
}
监控url变化
class VueRouter {
constructor(options) {const initial = window.location.hash.slice(1) || '/'
Vue.util.defineReactive(this, 'current', initial)window.addEventListener('hashchange', this.onHashChange.bind(this))
window.addEventListener('load', this.onHashChange.bind(this))
}
onHashChange() {
this.current = window.location.hash.slice(1)
}
}
动态获取对应组件
export default {
render(h) {
// 动态获取对应组件
let component = null;
const route = this.$router.$options.routes.find(route => route.path ===
this.$router.current)
if(route) component = route.component
return h(component);
}
}
提前处理路由表
class VueRouter {
constructor(options) {
// 缓存path和route映射关系
this.routeMap = {}
this.$options.routes.forEach(route => {
this.routeMap[route.path] = route
});
}
}
export default {
render(h) {
const {routeMap, current} = this.$router
const component = routeMap[current] ? routeMap[current].component : null;
return h(component);
}
}