在项目中npm i vue-router
在src下创建router文件夹,创建index.js文件
//createRouter 创建
//createWebHashHistory 哈希地址模式
//createWebHistory 地址模式
import { createRouter,createWebHashHistory,createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(), //路由url地址显示的模式
routes:[ //表示要配置的url地址和对应的view一一映射关系
{
path:'/home', //url路径地址
name:'home', //当前路由的名字
component:Home //对应的组件
},
{
path:'/login',
name:'login',
component:Login
}
]
})
export default router//默认导出
在main.js文件中挂载路由
import { createApp } from 'vue' //引入vue实例
import App from './App.vue'//引入app文件来创建实例
import router from '../src/router/index' //引入路由
const app = createApp(App) //创建vue实例
app.use(router)//挂载路由,这个必须写在.mount前面
app.mount('#app')//挂载
在App.vue文件中,占位符,路由的内容会显示在占位符位置
<template>
<div>
<h1>vue-router的app根组件</h1>
<ul>
<li>
<!-- 通过router-link to设置导航跳转位置 -->
<router-link to="/home">home导航</router-link>
</li>
<li>
<router-link to="/login">login导航</router-link>
</li>
</ul>
<!-- 路由的占位符,路由的内容显示到这个位置 -->
<router-view></router-view>
</div>
</template>
声明式导航
- 字符串式home导航
- 路径式home导航
- 命名式home导航
- 路径式和命名式导航的to前面要加:
编程式导航
在组件中引入
import { useRouter,useRoute } from 'vue-router';
const router = useRouter()
通过事件调用函数,执行跳转
const goto = ()=>{
//router.push('/news') 或者
//router.push({path:'/news'}) 或者
//router.push({name:'news'}) 或者
router.replace('/news')
}
- router.push与router.replace的区别
router.push跳转过去的地址可以返回回来,
router.replace跳转过去的地址会替换历史记录的当前位置,也就不能再跳转回来
roter.replace还有个写法,在router-link标签中直接加:replace - 前进和后退
const next = ()=>{
router.go(1)//前进下一次的地址
}
const prev=()=>{
router.back()//返回上一次地址
}
嵌套路由
在main.js文件中
import Login from '../views/login/login.vue'
import Zhangsan from '../views/login/zhangsan.vue'
import Lisi from '../views/login/lisi.vue'
const router = createRouter({
history: createWebHashHistory(),
routes:[
{
path:'/login',
name:'login',
component:Login,
redirect:'/login/zhangsan',//路由的重定向,默认展示该path路径的子路由
children:[ //在这里定义login路由下的子路由的参数
{
path:'/login/zhangsan',
name:'zhangsan',
component:Zhangsan,
},{
path:'lisi',
name:'lisi',
component:Lisi,
meta:{ //路由元信息
title:'标题'
}
},
]
}
]
})
export default router//默认导出
然后在login.vue文件内
<template>
<div>
<h1>我是login组件</h1>
<ul>
<li>
<router-link to="/login/zhangsan">跳转张三组件</router-link>
</li>
<li>
<router-link to="/login/lisi">跳转李四组件</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</template>
路由传参
在传递数据的组件中
<template>
<div>
<h1>我是user组件</h1>
<button @click="goHome">跳转到home并携带参数</button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
const goHome = ()=>{
// router.push('/home?name=隔壁老王')
// router.push({name:'home',query:{name:'隔壁老王',age:33}}) // 推荐用这种写法
router.push({path:'/home',query:{name:'隔壁老王',age:22}})
}
</script>
vue-router4.1.4之后的版本没有了parmas
在接收数据的页面组件中
<template>
<div>
<h1>我是home组件</h1>
<!-- 组件模板中直接当变量使用 -->
{
{ route.query }}
</div>
</template>
import { useRoute } from 'vue-router';
const route = useRoute()
console.log(route.query.name);
动态传参
在router.js中
//路由的path属性中
path: '/hot/:id', // :id 表示 后面的是一个动态参数
通过router-link 传递参数
<!-- to="/hot/这里放的就是对应id的值" -->
<router-link to="/hot/10">hot组件</router-link>
在路由到的页面,通过$route.params.id使用数据
//在模板中使用
{
{ $route.params }}
//在script中使用
console.log(route.params.id)
命名路由
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import InfoIndex from '../views/info/info.vue'
import InfoHeader from '../views/info/header.vue'
import InfoFooter from '../views/info/footer.vue'
const router = createRouter({
history: createWebHashHistory(), // 路由的url 地址显示的模式
routes: [ // 表示 要配置的url 地址和对应的view 一一映射关系
{
path: '/info',
name: 'info',
components: {
default: InfoIndex,//默认名字
header: InfoHeader,//头部
footer: InfoFooter//底部
}
}
]
})
在组件中,占位符加name,当跳转info时,显示的其实是三个组件占不同的位置
<router-view name="header"></router-view>
<router-view></router-view>
<router-view name="footer"></router-view>
路由重定向,默认展示页面
{
path: '/my',
name: 'my',
component: My,
redirect: '/my/lisi', // 重定向,当跳转这个路由时,重定向到指定路由地址
children: [
//进入页面默认展示
//{
// path: '',
// name: 'WW',
// component: WW,
//},
// 关于子路由的路径的写法 有2 种 第一种 完全写法 第二种写法 叫 携带 父路由的写法 千万不要加 /
{
path: '/my/zs',
name: 'zs',
component: ZS,
},
{
path: 'lisi', // 这里 千万不加 /
name: 'lisi',
component: LiSi,
meta:{ //路由元信息
title:'标题'
}
}
]
}
路由守卫
写在路由文件中
设置白名单
const whiteList = [‘/login’,‘/register’,‘/404’]
设置条件
router.beforeEach((to,from,next)=>{})
- to,即将要去到哪里
- from,从哪里来
- next,放行,符合规则就放行
全局的前置路由守卫
router.beforeEach((to,from,next)=>{
document.title = to.meta.title //动态切换标题,把标题切换成meta路由元信息描述的标题
let token = window.localStorage.getItem('token')
if(whiteList.includes(to.path)){
if(token){
next()
}else{
next()
}
}else{
if(token){
next()
}else{
next('/login')
}
}
})
- 后置路由守卫
router.afterEach((to, from, next)=>{
})