vue2-router 总结

vue2-router 总结

前言 import Home from ‘…/Home.vue’ 这行代码中的三个点“…” 是省略号的意思。

一、router 安装

1. 直接在脚手架中勾选

​ 新手使用 router 的时候,建议直接在使用脚手架创建 vue2 项目的时候,直接勾选,这样不容易安装错误对应的版本,导致一些错误。

2. 单独安装 ( vue2 ----> router3 )

npm i  vue-router@3.2.0

二、router配置

1. router文件配置

在 src 文件夹下面创建一个名为 router 的文件夹;在 router 文件夹中创建一个 index.js

import  Vue from 'vue'

import VueRouter from 'vue-router'

import Home from '.../Home.vue'

Vue.use(VueRouter)

// 路由表, 路由就是在这里配置,后面会详细讲解
const routes=[
    {
        path:'/home',
        component:Home
    }
]
// 创建一个路由实例
const router =new VueRouter({
    // hash 表示 hash 模式   history  表示 history 模式
    // 二者区别的表现在于地址栏有没有 # 
    mode:'hash',  
    routes
    
})

// 导出
export default router

2. 在 main.js 中的配置

在脚手架创建的项目中的入口文件(main.js)中导入,然后集成

import Vue from 'vue'

// 引入 router
import router from '...router/index.js'

// 引入根组件
import App from '..../App.vue'

new Vue({
    
    router:router,
    render:h=>h(App)
    
}).$mount("#app")

三、路由表的具体配置-routes

1. 普通路由配置

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'

const routes=[
    {
        // 基本的路由 配置 只需要这样两个属性即可
        path:'/home',  
        component:Home
    },
     {
        path:'/center',  
        component:Center
    },
]
1-1. 对应的声明式导航

当我们点击 router-link 的时候 ,

对应路径的组件会被加载到 <router-view></router-view>

// 声明式导航一
<router-link to="/home">首页</router-link>
<router-link to="/center">个人中心</router-link>

// 声明式导航二
<router-link :to="{path:'/home'}">首页</router-link>
<router-link :to="{path:'/center'}">个人中心</router-link>

// 这里是对应的组件的显示的标签
<router-view></router-view>
1-2. 对应的编程式导航
<button @click="onGoHome">首页</button>
<button @click="onGoCenter">个人中心</button>

// 这里是对应的组件的显示的标签
<router-view></router-view>

<script>
    export default {
        methods:{
            onGoHome(){
                // $router 代表的就是  new VueRouter()实例
                // 这里就是 编程式导航的路由跳转
                // this.$router.push('/home')  // 这里是第一种写法
                
                this.$router.push({path:'/home'})  // 也可以传入一个对象 第二种写法
			},
            onGoCenter(){
                // 这里就是 编程式导航的路由跳转
                // this.$router.push('/center')   // 这里是第一种写法
                
                this.$router.push({path:'/center'})  // 也可以传入一个对象 第二种写法
            }
	}
}

</script>

2. 命名路由

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'

const routes=[
    {
        path:'/home', 
        name:'home',  // 给路由添加一个 name 属性 就是命名路由了
        component:Home
    },
     {
        path:'/center', 
        name:'center', // 给路由添加一个 name 属性 就是命名路由了
        component:Center
    },
]
2-1. 对应的声明式导航
// 声明式导航
<router-link :to="{name:'home'}">首页</router-link>
<router-link :to="{name:'center'}">个人中心</router-link>

// 这里是对应的组件的显示的标签
<router-view></router-view>
2-2. 对应的编程式导航
<button @click="onGoHome">首页</button>
<button @click="onGoCenter">个人中心</button>

// 这里是对应的组件的显示的标签
<router-view></router-view>

<script>
    export default {
        methods:{
            onGoHome(){
                this.$router.push({name:'home'}) 
			},
            onGoCenter(){
                this.$router.push({name:'center'}) 
            }
	}
}
</script>

3. 动态路由

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'
import Info from '.../Info.vue'

const routes=[
    {
        // 动态路由就是在路径后面添加   /:参数名   参数名可以随意取
        path:'/home/:id',   
        name:'home', 
        component:Home
    },
     {
         // 动态路由就是在路径后面添加   /:参数名  参数名可以随意取
        path:'/center/:username',  
        name:'center', 
        component:Center
    },
     {
          // 动态路由就是在路径后面添加   /:参数名  参数名可以随意取  可以书写多个动态的
        path:'/info/:id/:uid', 
        name:'info', 
        component:Info
    },
]
3-1. 对应的声明式导航
3-1-1. 对应的声明式导航传参的动态路由-(直接拼接的模式)
// 直接拼接一个 (/参数即可)
<router-link to="/home/123">首页</router-link>

// 这里是对应的组件的显示的标签
<router-view></router-view>

获取对应的参数值:

<script>
    export default {
        created(){
        	console.log(this.$route.params.id)   // 获取对应的 id 的值
    }
}
</script>
3-1-2. 对应的声明式导航传参的动态路由-(传递一个对象的模式)-query
<router-link :to="{path:'/home',query:{id:123}">首页</router-link>

// 这里是对应的组件的显示的标签
<router-view></router-view>

获取对应的参数值:

<script>
    export default {
        created(){
        	console.log(this.$route.query.id)   // 获取对应的 username 的值
    }
}
</script>
3-2. 对应的编程式导航
// 这里是对应的组件的显示的标签
<router-view></router-view>
<button @click="onGoHome">首页</button>
<script>
    export default {
        methods:{
            onGoHome(){
                // 第一种写法-----111
				// this.$router.push('/home/'+123)  // '123' 也可以是一个变量
                
                // 第二种写法-----222
                this.$router.push({path:'/home',query:{id:123}})
            }
        }
}
</script>

获取对应的参数值:

<script>
    export default {
        created(){
            // 获取第一种写法的参数-----111
            // console.log(this.$route.params.id)
            
            // 获取第二种写法的参数-----222
           console.log(this.$route.query.id)
        }
}
</script>

4. 嵌套路由

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'

// 引入对应的组件
import Child1 from '.../Child1.vue'
import Child2 from '.../Child2.vue'

const routes=[
    {
        path:'/home',  
        component:Home,
// 嵌套路由就是 给路由添加一个 children 属性,属性值是一个数组,数组中在书写路由的配置即可
        children:[
            {
                path:'child1',  // 注意这儿的书写
                component:Child1
            },
            {
               path:'child2', // 注意这儿的书写
               component:Child2  
            }
        ]
    },
     {
        path:'/center',  
        component:Center
    },
]
4-1. 对应的声明式导航
// 以下代码 应该写在 home 组件中 对应的层级关系才正确
<router-link to="/home/child1">首页</router-link>

// 这里是对应的组件的显示的标签
<router-view></router-view>
4-2. 对应的编程式导航
// 这里是对应的组件的显示的标签
<router-view></router-view>
<button @click="onGoHomeChild1">首页/child1</button>
<script>
    export default {
        methods:{
            onGoHomeChild1(){
                // 第一种写法
				// this.$router.push('/home/child1')  
                
                // 第二种写法
                this.$router.push({path:'/home/child1'})
            }
        }
}
</script>

5. 命名视图

何为命名视图:命名视图就是一个 path 对应多个 component

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'
import Slide from '.../Slide.vue'

const routes=[
    {
        path:'/home',  
//这里就是命名视图,当路径是 /home 的时候,会显示下面的两个组件,需要页面做一些设置
        components:{
            default:Home,
            slider:Slide
        }
    },
     {
        path:'/center',  
        component:Center
    },
]
5-1. 对应的声明式导航
<router-link to="/home">首页</router-link>

// 这里是对应的组件的显示的标签
<router-view></router-view>   // 这个会加载 components 中的 default 的属性值
<router-view name="slider"></router-view>  // 这个会加载 components 中的 slider 的属性值
5-2. 对应的编程式导航
// 这里是对应的组件的显示的标签
<router-view></router-view>   // 这个会加载 components 中的 default 的属性值
<router-view name="slider"></router-view>  // 这个会加载 components 中的 slider 的属性值

<button @click="onGoHomeChild1">首页/嵌套路由</button>
<script>
    export default {
        methods:{
            onGoHomeChild1(){
                // 第一种写法
				// this.$router.push('/home/child1')  
                
                // 第二种写法
                this.$router.push({path:'/home/child1'})
            }
        }
}
</script>

6. 路由重定向

何为路由重定向:就是在匹配不到对应的路径的时候,就跳转到指定的路径;路由是从上往下匹配的,重定向一般写在最后面;

下面展示了:路由重定向,嵌套路由的重定向

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'

const routes=[
    {
        // 基本的路由 配置 只需要这样两个属性即可
        path:'/home',  
        component:Home
        children:[
            {
                path:'child1',  // 注意这儿的书写
                component:Child1
            },
            {
               path:'child2', // 注意这儿的书写
               component:Child2  
            },
    		{
// 嵌套组件的路由重定向
               path:'/home',
        	   redirect:'/home/child1' 
			}
        ]
    },
     {
        path:'/center',  
        component:Center
    },
    {
// 在上面的路由都不匹配的时候,就重定向到 /home  然后加载对应的组件
        path:'*',
        redirect:'/home'
    }
]

7. 路由懒加载

何为路由懒加载:就是在打开页面的时候,只加载,页面显示的模块。

// 引入 对应的组件
import Home from '.../Home.vue'
import Center from '.../Center.vue'

const routes=[
    {
        // 基本的路由 配置 只需要这样两个属性即可
        path:'/home',  
        component:()=>import('.../Home.vue')  // 按需加载模块,这就是懒加载
    },
     {
        path:'/center',  
        component:()=>import('.../Center.vue')  // 按需加载模块,这就是懒加载
    },
]

8. 路由元信息

import Home  from '.../Home'

const routes=[
    {
        path:'/home',
        component:Home,
        // meta 里面的信息就是路由元信息
        // 路由元信息中可以包含 图标 ,label 
        meta:{
            isAuthentication:true,
        }
    }
]

四、路由的传参的三种方式

4-1. 声明式导航路由传参的三种方式

第一种:动态路由传参-刷新不会丢失参数
const routes=[
    {
        path:'/detail/:id',
        name:'detail',
        component:Detail
    }
]
声明式导航传参
// 直接拼接即可
<router-link to="/detail/123">详情页</routerlink>

<router-view></router-view>
<router-link :to="{name:'detail',params:{id:123}}">详情页</routerlink>

<router-view></router-view>
<router-link :to="{name:'detail',query:{id:123}}">详情页</routerlink>

<router-view></router-view>
编程式导航传参
<button @click="OnGoDetail">
    详情页
</button>
<script>
methods:{
    OnGoDetail(){
        // 编程式导航的第一种写法,直接拼接参数
        // this.$router.push("/detail/123")
        //	this.$router.push("/detail/"+变量名)
        
        // 第二种写法
        // this.$router.push({name:'detail',params:{id:123}})
        
        // 第三种写法
         this.$router.push({name:'detail',query:{id:123}})
	}
}
</script>
第二种参方式-query-刷新不会丢失参数
const routes=[
    {
        path:'/detail',  // 注意这里的变化 和第一种有区别
        name:'detail',
        component:Detail
    }
]
对应的声明式导航
<router-link :to="{name:'detail',query:{id:123}}">详情页</routerlink>

<router-view></router-view>
对应的编程式导航
<button @click="OnGoDetail">
    详情页
</button>
<script>
methods:{
    OnGoDetail(){
        // 第三种写法
         this.$router.push({name:'detail',query:{id:123}})
	}
}
</script>
第三种传参方式-params-刷新会丢失参数
const routes=[
    {
        path:'/detail',  // 注意这里的变化 和第一种有区别
        name:'detail',
        component:Detail
    }
]
对应的声明式导航
<router-link :to="{name:'detail',params:{id:123}}">详情页</routerlink>

<router-view></router-view>
对应的编程式导航
<button @click="OnGoDetail">
    详情页
</button>
<script>
methods:{
    OnGoDetail(){
        // 第二种写法
           this.$router.push({name:'detail',params:{id:123}})
	}
}
</script>
总结
  • 使用动态路由传递参数:直接拼接,query,name配合params 都可以,都不会丢失参数。

  • 第二,三种传参方式:定义路由规则的时候,没有配置动态路由,那么只能query传参和params传参,params传递的参数看不到,安全性好,但是刷新数据会丢失;但是query传递参数是拼接在链接之后,所以刷新之后不会丢失,这种场景就是和需要分享的链接,可以保证拿到链接的人能看到数据和分享的人一样。

五、路由组件传参-第四种传参方式

const routes=[
    {
        path:'/home/:id',
        component:Home,
        props:true  // 注意这样一行代码
    }
]
// 对应的声明式导航一
<router-link to="/home/123">info</router-link>

// 对应的声明式导航二
<router-link :to="{name:'home',params:{id:123}}">首页</router-link>

// 这里对应的编程式导航略去了,和之前那些一样

获取对应的参数:

<script>
    export default {
        props:['id']
        created(){
			console.log(this.id)
        }
}
</script>

六、$route 与 $router

1. 二者区别

$route ------> 表示当前活跃的路由对象 ,就是地址栏对应的路径的路由对象

$router ------> 表示整个路由的实例对象,就是 router 文件夹下面的 index.js 文件中 使用 new VueRouter() 出来的那个 router

2. $router详解

this.$router.push()

// 编程式导航中使用
// 这个函数实现的跳转可以回退,具有历史记录
this.$router.push('/login')

this.$router.replace()

// 编程式导航使用
// 这个函数实现的跳转不会保留历史,不能回退
this.$router.replace('/login')

this.$router.go() this.$router.back() his.$router.forward()

// 这个函数有一个参数,正数表示前进一步,负数表示后退一步

// 前进一步
this.$router.go(1)

// 后退一步
this.$router.go(-1)

// 后退一步  相当于 go(-1)
this.$router.back()

// 前进一步,相当于 go(1)
this.$router.forward()

七、路由守卫

守卫函数中的参数:

to: 即将要进入的目标。

from: 当前导航正要离开的路由。

next:next 是一个函数,next() 执行下一个钩子;next( false ) 表示中断执行;

​ next( ‘/login’ ) 里面的参数可以是路由传参的参数设置一样。

​ next( ‘/login’ ) next( { path :’ /name ’ } ) next( { path :’ /name ', query : { id : 123 } } )

1. 全局守卫

全局前置守卫:
router.beforeEach((to,from,next)=>{
    // 在这里的面鉴权
})
1. 路由鉴权的第一种方式
  • 这种方式是通过路由白名单来实现的;路由白名单就是一个数组,将不需要鉴权的path放进去,在beforeEach触发的时候,判断一下是不是在数组中,在数组中直接放行即可;不在数组中的,就是需要鉴权的。
// 在src 目录下  新建一个 permission.js  
// 引入 路由表文件  router/index.js
import  router  from '.../router'

router.beforeEach((to,from,next)=>{
    
    const  routerArr=['/login','/regist','/home']
    
    if(routerArr.indexOf(to.fullPath) !== -1){
        // 直接放行
        next()
        return
	}
    let token = localStorage.getItem("TOKEN")
    if(token){
        // 直接放行
        next()
	}else{
        // 否则跳转至 登录界面
        next('/login')  // next 中支持 字符串参数,对象参数,参数+传值
	}
     
})

// 使用   在 main.js 文件中引入
import './permission.js'

new Vue({
    router,
    render:h=>h(App)
}).$mount("#app")
// 在src 目录下  新建一个 permission.js  
// 引入 路由表文件  router/index.js
import  router  from '.../router'

router.beforeEach((to,from,next)=>{
    
    const  routerArr=['/login','/regist','/home']
    
    // Array.includes() 可以用来判断数组中是否包含指定的值
    if(routerArr.includes(to.fullPath)){
        // 直接放行
        next()
        return
	}
    let token = localStorage.getItem("TOKEN")
    if(token){
        // 直接放行
        next()
	}else{
        // 否则跳转至 登录界面
        next('/login')  // next 中支持 字符串参数,对象参数,参数+传值
	}
     
})

// 使用   在 main.js 文件中引入
import './permission.js'

new Vue({
    router,
    render:h=>h(App)
}).$mount("#app")
2. 路由鉴权的第二种方式
  • 第二种路由鉴权的方式,使用的是元信息鉴权
const routes=[
    {
        path:'/main',
        component:Main,
        meta:{
			isAuthentication:true,
        }
	}
]
// 在src 目录下  新建一个 permission.js  
// 引入 路由表文件  router/index.js
import  router  from '.../router'

router.beforeEach((to,from,next)=>{
    // matched 是一个数组
    if(to.matched.some(item=>item.meta.isAuthentication)){
        // 直接放行
        next()
        return
	}
    let token = localStorage.getItem("TOKEN")
    if(token){
        // 直接放行
        next()
	}else{
        // 否则跳转至 登录界面
        next('/login')  // next 中支持 字符串参数,对象参数,参数+传值
	}
     
})

// 使用   在 main.js 文件中引入
import './permission.js'

new Vue({
    router,
    render:h=>h(App)
}).$mount("#app")
全局解析守卫:
router.beforeResolve((to)=>{
    // 未完待续
})
全局后置守卫:
router.afterEach((to,from)=>{
    // 未完待续
})

2. 独享守卫

const routes=[
    {
        path:'/home/:id',
        component:Home,
        props:true  // 注意这样一行代码
        beforeEnter:(to,from,next)=>{
    		// 和全局守卫的使用一样
    	}
    }
]

3. 组件内守卫

// 未完待续

八、路由的 hash 模式和 history 模式

初始化路由的时候,需要传入一个对象,包含mode,routes

import Vue from 'vue'
import VueRouter from  'vue-router'

Vue.use(VueRouter)

const routes=[
    {
        path:'/home',
        component:Home
    }
]

const router=new VueRouter({
      mode:'hash'  // 这个表示路由的 hash 模式
   // mode:'history'  // 这个表示路由的 history 模式
    routes
})
8-1. hash 与 history 的区别
8-1-1. 地址栏表现不一样:

​ hash 模式地址栏会出现一个 # ;history 模式不会出现,和请求服务器的 API 的地址一样。

8-1-2. 底层原理不一样:

hash模式使用的是 location.hash 实现的:

  • hash 将井号 # 拼接在真实 URL 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 hashchange 事件

history 使用的是 html5 的history对象实现的:

  • 用户点击浏览器的前进和后退操作,操作保存在history中的。
  • history 的 pushState()replaceState()方法

hash的优缺点:

  • 优点:浏览器兼容性较好,连 IE8 都支持
  • 缺点:路径在井号 # 的后面,比较丑

history的优缺点:

  • 优点:路径比较正规,没有井号 #
  • 缺点:兼容性不如 hash,且需要服务端支持,否则一刷新页面就404了

九、@/ 代表的意思

@/  === /src   // 这个应该看的懂了
// 这个@ 是可以改变的 需要去webpack中配置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值