当前位置: 首页 > Web前端 > vue.js

手写vue-router核心原理

时间:2023-03-31 19:27:57 vue.js

最近也在观察vue3的新特性,抽空玩玩嵌套路由的vue-router,直接进入代码项目目录结构代码展示app.vueIndex.vuePerson.vuePersonInfo.vuevue全家桶视频讲解:进入学习js文件main.jsimportVuefrom'vue'importAppfrom'./App.vue'importrouterfrom'./router'newVue({router,render:h=>h(App)}).$mount('#app')babel.config.js需要添加babel依赖来支持新的语法,比如optionalchainnpminstall--save-dev@babel/core@babel/clinpminstall--save-dev@babel/plugin-proposal-optional-chainingmodule.exports={预设:['@babel/preset-env'],插件:['@babel/plugin-proposal-optional-chaining']}router目录文件index.jsimportVuefrom"vue";importVueRouterfrom"./vue-router";importIndexfrom"../views/Index.vue";importPerson来自“../views/Person.vue”;从“../views/PersonInfo.vue”导入PersonInfo;Vue.use(VueRouter);constroutes=[{path:"/",name:"Index",component:Index},{path:"/person",name:"Person",组件:Person,children:[{path:"/person/info",name:"PersonInfo",component:PersonInfo}]}];constrouter=newVueRouter({routes});exportdefaultrouter;vue-router.js这里首先使用Vue的工具Vue。util.defineReactive实现了数据响应,后来手工撕掉了这个库$options=optionsthis.current=window.location.hash.slice(1)||"/"//设置响应式数组数据Vue.util.defineReactive(this,"routerArray",[])//监听哈希值变化window.addEventListener("hashchange",this.hashChange.bind(this))this.getRouterArray()}hashChange(){this.current=window.location.hash.slice(1)||“/”this.routerArray=[]this.getRouterArray()}getRouterArray(routes){routes=routes||this.$options.routesfor(constrouteofroutes){if(this.current==='/'&&route.path==='/'){this.routerArray.push(route)return}if(this.current.indexOf(route.path)!==-1&&route.path!=='/'){this.routerArray.push(route)if(route.children){//递归子路由this.getRouterArray(route.children)}return}}}}VueRouter.install=function(_Vue){Vue=_Vue//Vueglobalmixin,newVue中的router实例创建完成后,挂载到Vue上});//注册router-link和router-view全局组件Vue.component("router-link",routerLink)Vue.component("router-view",routerView)}exportdefaultVueRouterrouter-link.jsexportdefault{props:{to:{type:String,required:true}},render(h){returnh("a",{attrs:{href:"#"+this.to,},},this.$slots.默认);}};router-view.jsexportdefault{render(h){//设置嵌套路由标识符this.$vnode.data.rv=true//设置嵌套路由的深度letdepth=0letparent=this.$parentwhile(parent){//parent有嵌套路由标志rv为真,深度加一if(parent.$vnode?.data?.rv){depth++}parent=parent.$parent}//简单处理constroute=this.$router.routerArray[depth]returnh(route?.component);}};效果图做好了,今天先玩到这里,下次再玩其他游戏