实现vue-router部分功能
前端  /  管理员 发布于 6年前   208
目的
为了了解路由的底层工作原理,自己参考资料,仿写了vue-router的部分功能。当然自己写的DEMO功能较粗糙,主要实现核心功能,其它功能有待完善、补充。
参考vue-router,我们实现路由插件的api、组件尽量保持跟vue-router一样;
首先添加一个SRouter类,来模拟vue-router插件的功能,暂且不管类的实现;
提供router.js文件,然后new SRouter(options),options传递的就是所有的组件路径以及路由访问路径,结构同使用vue-router,只是new的对象不一样,我们new的是自己实现的路由类;
接着来实现SRouter类,主要包括以下几步:
a. 首先在类中提供静态的intall函数,方便Vue.use调用,在里面来调用路由的初始化函数
b. 注册router-link、router-view组件
c. 监听hashchange事件,获取路由对应的组件,router-view装载对应的组件
d. 处理钩子函数
实现以上几步,可以满足路由的基本功能。
主要贴出部分关键代码,具体可以参考源码地址
1. SRouter类:a. 首先在类中提供静态的intall函数,方便Vue.use调用,在里面来调用路由的初始化函数
主要解释下intall里面为什么使用mixin,这是为了在创建vue实例后调用我们的路由初始化工作;然后constructor中使用new Vue()主要是为了使用vue的数据响应式,能自动检测到数据的变化;
static install(_vue) { Vue = _vue Vue.mixin({ beforeCreate() { //这里的router就是我们在new Vue的时候传递的router对象 if (this.$options.router) { Vue.prototype.$srouter = this.$options.router this.$options.router.init() } } }) } constructor(opitons) { this.$options = opitons this.routeMap = {} this.app = new Vue({ data: { current: '/' } }) } //路由初始化函数 init() { //启动路由 //1.初始化组件router-link router-view this.initComponent() //2.监听hashchange事件 this.handleEvents() //3.处理路由 this.createRouterMap() //3.处理钩子函数 }
b. 注册router-link、router-view组件
//初始化组件 router-view router-link initComponent() { Vue.component('router-view', { render: h => { const component = this.routeMap[this.app.current].component //使用h新建一个虚拟dom return h(component) } }) Vue.component('router-link', { props: { to: String }, render(h) { return h('a', { attrs: { href: '#' + this.to } }, [this.$slots.default] ) } }) }
c. 监听hashchange事件,获取路由对应的组件,router-view装载对应的组件
//注册监听事件 handleEvents() { window.addEventListener('hashchange', this.onHashChange.bind(this), false) window.addEventListener('load', this.onHashChange.bind(this), false) } //监听hash改变 onHashChange(e) { //路由跳转 let hash = window.location.hash.slice(1) || '/' let router = this.routeMap[hash] if (router && router.beforeEnter) { let [from, to] = [e.oldURL?.split('#')[1], e.newURL?.split('#')[1] || '/'] router.beforeEnter(from, to, () => { this.app.current = hash }) } else { this.app.current = hash } }
2. router.js文件,基本完全同vue-router的router.js文件,只是我们引入的是SRouter对象;import Vue from 'vue'import SRouter from './s-router'Vue.use(SRouter)export default new SRouter({ routes: [ { name: 'index', path: '/', component: () => import('./views/index'), beforeEnter(from, to, next) { //处理异步请求 setTimeout(()=>{ next() }) } }, { name: 'about', path: '/about', component: () => import('./views/about') } ]})
来自:https://my.oschina.net/u/4291402/blog/4321607122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号