vue-router简易原理

router任务分析

解析routes选项

使用 vue-router 时,需要创建一个 .js 后缀的文件,该文件内会出现下列代码,即声明 vue 安装了该插件,但是在初学 vue 时,你会发现mian.js中存在如下代码,那么为何安装了插件同时还要在根实例上配置 router 实例

#  router.js
...
Vue.use(Router);
...

# main.js
...
new Vue({
  data: {
    bar: 'bar'
  },
  router,  // 【此处重点】配置router实例
  store,
  render: h => h(App)
}).$mount("#app");

监控URL变化、实现全局组件(router-link、router-view)

两种方式:一种 history【监听历史记录改变】,一种监听 hash 改变

  • html5 history api -- xx.html/login
  • hash xx.html#/login
    注意:声明Vue插件需求实现一个install的静态方法)
let Vue; // 保存Vue构造函数引用
class KVueRouter {
	constructor(options) {
		this.$options = options;
		this.routeMap = {}; // {'/index': { component:Index,... }}
		
		// 当前url需要是响应式的
		this.vm = new Vue({
			data: { current: '/' }
		});
	}
	// 初始化
	init() {
		// 监听事件
		this.bindEvents();
		// 解析routers
		this.createRouteMap();
		// 声明组件
		this.initComponent();
	}
	bindEvents() {
		window.addEventListener('hashchange', this.onHashchange.bind(this))
	}
	onHashchange() {
		this.app.current = window.location.hash.slice(1) || '/'
	}
	createRouteMap() {
		// 遍历用户配置路由数组
		this.$options.routes.forEach(item => {
			this.routeMap[item.path] = route;
		});
	}
	initComponent() {
		// 转换目标: <a href="/">xxx</a>
		// <router-link to="/">
		Vue.component('router-link', {
        	props: {
				to: String,
			},
			render(h) {
				// h(tag, data, children)
				// 使用createElement函数
				return h('a', {
					attrs: { href: '#' + this.to }
				}, [this.$slots.default)]);
				// 使用jsx
				// return <a href={'#' + this.to}>{this.$slots.default}}</a>;
			}
        })
	}
}

// 参数是Vue构造函数
KVueRouter.install = function(_Vue) {
	Vue = _Vue;
	/* 为何不直接在此处定义$router,而舍近求远的建立一个混合呢?
	Vue.use(Router) 是定义在router.js文件夹的,此时vue实例尚未初始化,this无法获取到实例。
	 Vue.prototype.$router = this.$options.router;
	*/
	// 实现一个混入
	Vue.mixin({
		beforeCreate() {
			// this.$optinos 获取当前Vue实例的初始化选项【对象参数】。需要在选项中包含自定义属性时会有用处:
			// 获取KVueRouter实例并挂载到Vue.prototype
			if (this.$options.router) {
				/*  只在根组件beforeCreate时执行一次、
				    这也是为什么根组件初始化对象中含有router属性
				  new Vue({
					  data: {
					    bar: 'bar'
					  },
					
					  router, // 配置router实例
					  store,
					  render: h => h(App)
					}).$mount("#app");
				*/
				Vue.prototype.$router = this.$options.router;
			}
		}
	})
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值