Vue-Router 源码浅尝辄止
基本用法
-
安装:
npm install vue-router --save-dev; -
通常 创建router 文件夹用来管理路由
上图是一个常用的 vue-cli的脚手架目录
-
Index.js. 用来导出一个 vue-router 对象
import Vue from 'vue' // import VueRouter from 'vue-router'; 注释调 之前vue-cli引入的 vue-router import VueRouter from './vueRouter.js'; // 改用我们自己的vue-router import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] const router = new VueRouter({ routes }) export default router -
Main.js 中注册router
import Vue from 'vue' import App from './App.vue' import router from './router' Vue.config.productionTip = false new Vue({ router, render: h => h(App) }).$mount('#app')
-
-
分析需求. usage :
- spa页面不能刷新,根据url显示对应的内容
- Vue-router 是一个插件 所以必须有静态方法 install
- 为了在每个vue 组件中使用。
this.$router需要给Vue.prototype.$router 挂在vue-router 实例 - 全局组件vue-router vue-review 不是白来的 需要全局注册
- 定义一个 响应式的数据 并监听
hashchange事件 ,接受注册的路由表,跳转对应的组件
实现一个简单的hash mode router
该代码和 vue-router 是有些许的差别的,请自行研究具体细节
let Vue;
class VueRouter {
constructor(options) {
this.$options = options;
this.matcher = createMatcher(options.routes || [],this);
}
init(app){
// 为了简化 这里和源码有些出入
const initial = window.location.hash.slice(1) || "/";
Vue.util.defineReactive(app, '_route', this.matcher[initial])
window.addEventListener("hashchange", () => {
app._route = this.matcher[window.location.hash.slice(1)]
})
}
}
VueRouter.install = function (_Vue) {
Vue = _Vue;
Vue.mixin({
beforeCreate() {
if (this.$options.router) {
this._routerRoot = this;
this._router = this.$options.router;
this._router.init(this);
}else{
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
}
}
})
Object.defineProperty(Vue.prototype, '$router', {
get () { return this._routerRoot._router }
})
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
Vue.component('router-link', {
props: {
to: {
type: String,
required: true
}
},
render(h) {
return h("a", { attrs: { href: "#" + this.to } }, this.$slots.default)
}
});
Vue.component('router-view', {
render(h) {
let component = null;
if(this.$route.component){
component = this.$route.component;
}
return h(component);
}
});
}
const createMatcher = function(routes){
let obj = {};
routes.forEach(route=>{
obj[route.path] = route;
})
return obj;
}
export default VueRouter;
这样一个简单的 hashchange 的vue-router 就实现了