VueRouter官方路由管理器。它与Vue.js的核心深度集成,可以轻松构建单页应用程序。VueRouter目标:手动实现简单的vue-roter功能1.实现VueRouter类和安装方法2.实现router-view,router-link3.监听url变化:hashchange或popstate4.响应url开发环境:package.json"vue":"^2.6.11","vue-router":"^3.3.2"在vue中,vue-router的用法src/router/index.jsimportVuefrom'vue'importVueRouterfrom'vue-router'importHomefrom'../views/Home.vue'Vue.use(VueRouter)//这里首先使用Vue的use方法来使用VueRouter,调用VueRouter插件的install方法。constroutes=[{path:'/',name:'Home',component:Home},{path:'/about',name:'About',component:()=>import(/*webpackChunkName:"about"*/'../views/About.vue')}]constrouter=newVueRouter({//需要一个VueRouter类mode:'history',base:process.env.BASE_URL,routes})exportdefaultrouterouter/src/main.js在根组件上添加这个实例newVue({router,render:h=>h(App)}).$mount('#app')创建自己的kvue-routersrc/krouter自己创建的kvue-routersrc/krouter/index.js路由的入口其实和默认导入的src/router/index.js是一样的。刚刚修改,importVueRouterfrom'./kvue-router2';将导入位置改为自己写的kvue-routerkvue-router.js。kvue-router2.js和kvue-router2.js的区别在于kvue-router2.js进行了优化。接下来会解释。实现简单的vue-router函数src/krouter/kvue-router.js//引用传入的_vue构造函数,类VueRouter中需要使用的_vue所以设置一个全局的letVue;vue//vuerouter这个类//实现install方法,一个类需要使用install方法//vuerouter是一个类外部用法是:newVueRouter(routers:[...])krouter/kvue-router.jsclassVueRouter{//需要在这个Incoming路由中处理pass//"要获取传入的props,需要使用构造函数;"需要知道在使用newVueRouter(routers:[...])时,参数constructor(options){传入routers//方便在其他地方使用this.$options=options//保存options用于备份//createcurrent保存当前url//为了让currentbuild重新渲染应该是responsivedata//this.current='/'这种写法是行不通的//使用Vue中的defineReactive方法给对象赋一个属性来响应。Vue.util.defineReactive(this,'current','/')//为当前VueRouter设置一个响应式数据//监听hashchange事件监听url的变化window.addEventListener('hashchange',this.onHashChange.bind(this))//Changethis}//当路由发生变化时,改变当前router-viewonHashChange(){//修改当前url值,获取的hash需要修改;hash格式为:#/.....this.current=window.location.hash.slice(1)console.log(this.current)}}//实现静态install方法//参数1为Vue的构造函数Vue.use(VueRouter);use使用install方法;所以_vue接收的是vue构造函数VueRouter.install=function(_vue){Vue=_vue//挂载VueRouter实例创建的实例放在main.js中newVue({router,...})也需要在vue中使用this.$router,所以需要挂载build//通过options获取,但是options是构建实例的选项,不是构造函数//因为newVue({router,...})会有一个instance,所以需要在生命周期中实现//为了能够在Vue根实例中获取router实例//可以使用mixin实现全局混合Vue.mixin({//mixins之后defined,所有的组件都会经历写在里面的生命周期,因为定义在beforeCreate中,所以newVue({router,...})会被执行。已经可以拿到router实例了//为什么还要在生命周期中使用它,因为只有在生命周期中才能找到全局的thisrootstrength;Vue.mixins是全局的beforeCreate(){//只有在Vue的根实例中才会有.router//区分什么是根组件和根实例;newVue是根实例App是根组件//所以需要判断if(this.$options.router){//这是单例模式,拿到后赋值Vue.prototype.$router=this.$options.router}}})//需要注册两个组件XXXX是插槽内容Vue.component('router-link',{//router-link的使用是:props:{to:{type:String,//当前做的是一个简单的类型,其实to属性可以是对象的default:''}},render(h){//参数一标签类型//参数二传入的各种属性和事件//一般写法returnh('a',{attrs:{href:'#'+this.to}},this.$slots.default)//你也可以使用jsx语法return{this.$slots.default}//不是推荐使用jsx,因为开发组件库或插件时,不应该要求用户准备jsx环境,不通用,目前可以b因为目前是cli环境}})Vue.component('router-view',{render(h){//console.log('router-viewrender',this.$router)//挂在组件里,this.$touterletcomponent=null;//console.log(this.$router.$options.routes)const{$options,current}=this.$router;//console.log($options,current)constrouter=$options.routes.find((item)=>{returnitem.path===current})//console.log(router)if(router){component=router.component}returnh(component)}})}exportdefaultVueRouter接下来优化src/krouter/kvue-router2.js//引用传入的_vue构造函数,_vue需要在类VueRouter中使用,所以设置一个全局的让Vue;Vue//vuerouter这个类//实现了install方法,一个类需要使用install方法//vuerouter是一个类的外部用法是:newVueRouter(routers:[...])krouter/kvue-router.jsclassVueRouter{//在这种情况下,需要处理传入的路由//"它需要用于获取传入的props构造函数;"需要知道,在使用newVueRouter(routers:[...])时,routers中传入的参数constructor(options){//其他地方使用this.$options=options比较方便//保存options以备后用//createcurrent保存当前url//以便current重新-render,它应该是一个响应式数字根据//this.current='/'这种写法是行不通的//处理路由this.routeMap={}this.$options.routes.forEach(route=>{this.routeMap[route.path]=route})//使用vue中的defineReactive方法为对象指定一个属性响应Vue.util.defineReactive(this,'current','/')//为当前VueRouter设置一个响应式数据//监听hashchange事件监听url的变化window.addEventListener('hashchange',this.onHashChange.bind(this))//Changethis}//当路由发生变化时,改变当前router-viewonHashChange(){//修改当前url值,获取的hash需要修改;hash格式为:#/.....this.current=window.location.hash.slice(1)console.log(this.current)}}//实现静态install方法//参数1为Vue的构造函数Vue.use(VueRouter);use使用install方法;所以_vue接收的是vue构造函数VueRouter.install=function(_vue){Vue=_vue//挂载VueRouter实例创建的实例放在main.js中newVue({router,...})也需要在vue中使用this.$router,所以需要挂载build//通过options获取,但是options是构建实例的选项,不是构造函数//因为newVue({router,...})会有一个instance,所以需要在生命周期中实现//为了能够在Vue根实例中获取router实例//可以使用mixin实现全局混合Vue.mixin({//mixins之后defined,所有的组件都会经历写在里面的生命周期,因为定义在beforeCreate中,所以newVue({router,...})会被执行。已经可以拿到router实例了//为什么还要在生命周期中使用它,因为只有在生命周期中才能找到全局的thisrootstrength;Vue.mixins是全局的beforeCreate(){//只有在Vue的根实例中才会有.router//区分什么是根组件和根实例;newVue是根实例App是根组件//所以需要判断if(this.$options.router){//这是单例模式,拿到后赋值Vue.prototype.$router=this.$options.router}}})//需要注册两个组件XXXX是插槽内容Vue.component('router-link',{//router-link的使用是:props:{to:{type:String,//当前做的是一个简单的类型,其实to属性可以是对象的default:''}},render(h){//参数一标签类型//参数二传入的各种属性和事件//一般写法returnh('a',{attrs:{href:'#'+this.to}},this.$slots.default)//你也可以使用jsx语法return{this.$slots.default}//不是推荐使用jsx,因为开发组件库或插件时,不应该要求用户准备jsx环境,不通用,目前可以b因为目前是cli环境}})Vue.component('router-view',{//简单路由处理,无需递归render(h){const{routeMap,current}=this.$routerconstcomponent=routeMap[current]?routeMap[current].component:nullreturnh(component)}})}exportdefaultVueRoutersrc/main.js的修改主要是修改介绍,改成自己写的krouter