手动实现vue-router(hash)

实现VueRouter需要做到三点:
1.处理路由选项
2.监听url变化
3.如何响应url变化

cvue-router


// 因为vuerouter是个插件,需要实现一个install方法

// 1.$router注册, 2、声明全局组件<rouet-link><router-view>

// 自己写router
// 1.VueRouter类是一个插件
let Vue
class VueRouter {
	// options 是routes里面的配置项
	constructor(options) {
		this.$options = options;
		
		//声明current(默认url地址)
		// 把current设置为响应式数据
		const initial = this.current = window.location.hash.slice(1) || '/'
		Vue.util.defineReactive(this, 'current', initial)
		// this.current = window.location.hash.slice(1) || '/'
		console.log(this.current)
		//监听url变化,hashchange监听hash
		window,addEventListener('hashchange', ()=> {
			this.current = window.location.hash.slice(1)
			console.log(this.current)
		})
	}
}  //1。声明默认地址(响应式,为后面router-view重复渲染做准备) 2. 监听地址变化

// 插件实现(VueRouter需要实现一个install方法)
// 参数 1. vue的构造函数
VueRouter.install = function(_Vue) {  // install 调用
	// 保存构造函数的引用
	Vue = _Vue;   // 保存好处:vue作为形参打包的时候插件是独立库打包的时候不会叭vue打包进去
	// 挂载$router到vue原型
	// 利用全局混入延迟执行下面代码,可以实现获取router
	Vue.mixin({
		beforeCreate() {
			// this指的组件实例
			if (this.$options.router) {
				Vue.prototype.$router = this.$options.router
			}
		}
	})
	// Vue.prototype.$router = 
	
	// 3.声明全局组件<router-view><router-link>
	
	Vue.component('router-link', {
		props: {
			to: {
				type: String,
				required: true
			}
		},
		// 只可以使用render,不可使用模版语法因为当前环境下没有编译器
		// this指向当前的组件实例
		render(h) {
			return h('a', {attrs: {href: '#' + this.to}}, this.$slots.default)
		}
	})
	Vue.component('router-view', {
		// render(h) {
		// 	return h('div', 'hello')
		// }
		// 这里this指的router-view
		render(h) {
			// 获取vuerouter里面的current(this.$router.current)
			console.log(this.$router, 'current')  // 渲染函数要重新执行内部数据必须是响应式的数据
			// 监听router变化切换组件
			// this.$router.mate 
			// 根据current获取路由表中对应的组件
			let component = null;
			
			const route = this.$router.$options.routes.find(route => route.path === this.$router.current)
			if (route) {
				component = route.component
			}
			console.log(component)
			return h(component)
		}
	})
}

export default VueRouter;

index.js

import Vue from 'vue'
import VueRouter from './cvue-router.js'
import Home from '../views/Home.vue'
// 数据响应式?
// 1.router插件做了什么为什么要use一下
// 2.创建的router为什么要在new Vue()里面声明挂载一下: (挂载之后每个组件都可以访问$router,可以对路由进行访问做一些命令式的导航)
// 3.router-view和router-link为什么可以直接使用(因为直接全局申明了)


// 基于hashchange的实现

Vue.use(VueRouter)  // vuerouter插件使用1

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({   // 2创建实例
  mode: 'hash',
  base: process.env.BASE_URL,
  routes
})

export default router


// 3.挂载到vue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值