当前位置: 首页 > Web前端 > JavaScript

Vue-Router实现原理

时间:2023-03-27 18:33:18 JavaScript

Hash和History模式Hash模式http://localhost.com/#/user/idHash模式是基于anchors和onhashchange事件。通过window.location.href更改浏览器地址。如果只更改#后面的地址,则不会触发服务器请求,#后面的值会作为路由地址。当地址发生变化时,会触发onhashchange事件,监听该事件并做相应处理。切换显示不同组件History模式http://localhost.com/user/idHistory模式是基于HTML5中的HistoryAPI通过history.pushState()方法改变浏览器地址,只会改变浏览器地址,不会改变发送给服务器的请求,并在浏览器的历史记录中记录当前地址向服务器发送请求,replaceState不会新增新的历史栈记录,而是替换当前url监听popstate事件,可以监听浏览器历史数据的变化。事情不会在pushStash或replaceStash中触发,只会在浏览器向前或向后移动时触发根据当前路由地址找到对应的组件重新渲染nginx环境配置location/{roothtml;indexindex.htmlindex.htm;#新增内容#尝试读取$uri(当前请求的路径),如果读取不到,读取$uri/这个文件夹下的首页#如果读取不到,返回index.html在根目录try_files$uri$uri//index.html;}模拟创建一个VueRouter插件,静态方法install判断插件是否加载。Vue加载时,将传入的router对象挂载到Vue实例中(全局混合的目的是获取Vue实例)创建VueRouter类初始化,options,routeMap,data(路径,创建一个Vue实例作为响应式数据记录currentpath)createRouteMap()遍历所有路由信息,将组件和路由的映射记录到routeMap对象中当前路径当路径发生变化时,通过当前路径在routerMap对象中找到对应的组件,渲染router-viewlet_Vue=null;exportdefaultclassVueRouter{constructor(options){this.options=options;this.routeMap={};this.data=_Vue.observable({current:"/",});this.createRouteMap();this.initComponent(_Vue);这个.initEvent();}staticinstall(Vue){//1判断当前插件是否安装if(VueRouter.install.installed){re转动;}VueRouter.install.installed=true;//2在全局中记录Vue构造函数_Vue=Vue;//3注入传递给Vue实例的路由器对象//_Vue.prototype。$router=this.$options.router_Vue.mixin({beforeCreate(){if(this.$options.router){_Vue.prototype.$router=this.$options.router;}},});}//遍历所有的路由规则,将路由规则解析成键值对存储在routeMap中createRouteMap(){this.options.routes.forEach((route)=>{this.routeMap[route.path]=route.component;});}//创建router-link和router-view组件initComponent(Vue){Vue.component("router-link",{props:{to:String,},render(h){returnh("a",{attrs:{href:this.to,},on:{click:this.clickHandler,},},[this.$slots.default]);},methods:{clickHandler(e){//改变地址,do不发送请求,记录地址历史history.pushState({},"",this.to);this.$router.data.current=this.to;//阻止后续执行,防止超链接跳转e.preventDefault();},},//模板:"<>"});常量自我=这个;Vue.component("router-view",{render(h){constcm=self.routeMap[self.data.current];returnh(cm);},});}//注册popstate事件,当路由地址改变时,重新记录当前路由initEvent(){window.addEventListener("popstate",()=>{this.data.current=window.location.pathname;});}}