Vue | Vue3官方库(Vue Router)

1. 路由机制Router
1.1 路由简介
1.什么是路由?
- 定义:路由就是根据不同的 URL 地址展示不同的内容或页面;
- 通俗理解:路由就像是一个地图,我们要去不同的地方,需要通过不同的路线进行导航;
2.路由的作用:
- 单页应用程序(SPA)中,路由可以实现不同视图之间的无刷新切换,提升用户体验;
- 路由还可以实现页面的认证和权限控制,保护用户的隐私和安全;
- 路由还可以利用浏览器的前进与后退,帮助用户更好地回到之前访问过的页面;
1.2 路由入门案例
- 案例需求分析:

- 创建项目和导入路由依赖:
pnpm create vite //创建项目cd 项目文件夹 //进入项目文件夹
pnpm install //安装项目需求依赖
pnpm install vue-router@4 --save //安装全局的vue-router 4版本, --save表示添加依赖到package.json,默认可省略。--save-dev表示增加开发依赖配置。- 准备页面和组件:
components/Home.vue
<script setup>
</script>
<template>
<div>
<h1>Home页面</h1>
</div>
</template>
<style scoped>
</style>
components/List.vue
<script setup>
</script>
<template>
<div>
<h1>List页面</h1>
</div>
</template>
<style scoped>
</style>
components/Add.vue
<script setup>
</script>
<template>
<div>
<h1>Add页面</h1>
</div>
</template>
<style scoped>
</style>
components/Update.vue
<script setup>
</script>
<template>
<div>
<h1>Update页面</h1>
</div>
</template>
<style scoped>
</style>
App.vue
<script setup>
</script>
<template>
<div>
<h1>App页面</h1>
<hr />
<!-- 路由的连接,用于切换路由(切换到不同组件) -->
<router-link to="/">home页</router-link> <br>
<router-link to="/list">list页</router-link> <br>
<router-link to="/add">add页</router-link> <br>
<router-link to="/update">update页</router-link> <br>
<hr />
<!-- 路由连接对应视图的展示位置 -->
<hr> 默认展示位置:<router-view></router-view>
<hr> Home视图展示:<router-view name="homeView"></router-view>
<hr> List视图展示:<router-view name="listView"></router-view>
<hr> Add视图展示:<router-view name="addView"></router-view>
<hr> Update视图展示:<router-view name="updateView"></router-view>
</div>
</template>
<style scoped>
</style>- 准备路由配置:
src/routers/router.js
// 导入路由创建的相关方法
import {createRouter,createWebHashHistory} from 'vue-router'
// 导入vue组件
import Home from '../components/Home.vue'
import List from '../components/List.vue'
import Add from '../components/Add.vue'
import Update from '../components/Update.vue'
// 创建路由对象,声明路由规则
const router = createRouter({
//createWebHashHistory() 是 Vue.js 基于 hash 模式创建路由的工厂函数。在使用这种模式下,路由信息保存在 URL 的 hash 中,
//使用 createWebHistory() 方法,可以创建一个路由历史记录对象,用于管理应用程序的路由。在 Vue.js 应用中,
//通常使用该方法来创建路由的历史记录对象。
//就是路由中缓存历史记录的对象,vue-router提供
history: createWebHashHistory(),
routes:[
{
path:'/',
/*
component指定组件在默认的路由视图位置展示
components:Home
components指定组件在name为某个值的路由视图位置展示
components:{
default:Home,// 默认路由视图位置
homeView:Home// name为homeView的路由视图位置
}
*/
components:{
default:Home,
homeView:Home
}
},
{
path:'/list',
components:{
listView : List
}
},
{
path:'/add',
components:{
addView:Add
}
},
{
path:'/update',
components:{
updateView:Update
}
},
]
})
// 对外暴露路由对象
export default router;- main.js引入Router配置:
修改文件:main.js (入口文件)
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 导入Reouter模块
import router from './routers/router.js'
// 绑定路由对象到Vue实例上
createApp(App).use(router).mount('#app')
// 也可以分开写
// const app = createApp(App) // 创建Vue实例
// app.use(router) // 绑定路由对象到Vue实例上
// app.mount('#app') // 挂载Vue实例到页面上- 启动测试:
pnpm dev内容解释: https://router.vuejs.org/zh/guide/
1. RouterLink 用来渲染一个链接的组件,该链接在被点击时会触发导航。
<router-link to="/list">list页</router-link> <br> to属性指的是触发路径跳转到对应组件
2. RouterView RouterView 组件可以使 Vue Router 知道你想要在哪里渲染当前 URL 路径对应的路由组件。它不一定要在 App.vue 中,你可以把它放在任何地方!
可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为default
<router-view class="view left-sidebar" name="LeftSidebar" />
3. createRouter()函数
路由器实例是通过调用 createRouter() 函数创建的
const router = createRouter({
history: createMemoryHistory(), //记录历史记录模式!
routes:[
path: "/对应地址",component: 默认routerView显示组件,
path: "/对应路径",components:{命名视图名:显示组件,命名视图名:显示组件}
] //路由规则
})
路径:动态路径设置,路径传惨
/users/:username /users/eduardo
/users/:username/posts/:postId /users/eduardo/posts/123
{{ $route.params.username }} 获取参数
4. 注册路由器插件
createApp(App)
.use(router)
.mount('#app')
注册路由作用:
全局注册 RouterView 和 RouterLink 组件。
添加全局 $router 和 $route 属性。
启用 useRouter() 和 useRoute() 组合式函数。
触发路由器解析初始路由。1.3 路由重定向
重定向的作用:将一个路由重定向到另一个路由上。
- 修改案例:访问/list和/showAll都定向到List.vue.
- router.js
{
path:'/showAll',
// 重定向
redirect :'/list'
}- App.vue
<script setup>
</script>
<template>
<div>
<h1>App页面</h1>
<hr/>
<!-- 路由的连接 -->
<router-link to="/">home页</router-link> <br>
<router-link to="/list">list页</router-link> <br>
<router-link to="/showAll">showAll页</router-link> <br>
<router-link to="/add">add页</router-link> <br>
<router-link to="/update">update页</router-link> <br>
<hr/>
<!-- 路由连接对应视图的展示位置 -->
<hr> 默认展示位置:<router-view></router-view>
<hr> Home视图展示:<router-view name="homeView"></router-view>
<hr> List视图展示:<router-view name="listView"></router-view>
<hr> Add视图展示:<router-view name="addView"></router-view>
<hr> Update视图展示:<router-view name="updateView"></router-view>
</div>
</template>
<style scoped>
</style>
1.4 编程式路由(useRouter)
声明式路由:
<router-link to="/list">list页</router-link>这种路由,点击后只能切换/list对应组件,是固定的。
编程式路由:
通过useRouter,动态决定向那个组件切换的路由;
在 Vue 3 和 Vue Router 4 中,你可以使用
useRouter来实现动态路由(编程式路由);这里的
useRouter方法返回的是一个 router 对象,你可以用它来做如导航到新页面、返回上一页面等操作;声明式 编程式 <router-link :to="...">router.push(...)// 字符串路径 router.push('/users/eduardo') // 带有路径的对象 router.push({ path: '/users/eduardo' }) // 带查询参数,结果是 /register?plan=private router.push({ path: '/register', query: { plan: 'private' } router.push(`/user/${username}`) // -> /user/eduardo // 同样 router.push({ path: `/user/${username}` }) // -> /user/eduardo // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益 router.push({ name: 'user', params: { username } }) // -> /user/eduardo // `params` 不能与 `path` 一起使用 router.push({ path: '/user', params: { username } }) // -> /user
案例需求:通过普通按钮配合事件绑定实现路由页面跳转,不直接使用router-link标签。
- App.vue
<script setup type="module">
import {useRouter} from 'vue-router'
import {ref} from 'vue'
//创建动态路由对象
let router = useRouter()
let showList= ()=>{
// 编程式路由
// 直接push一个路径
// router.push('/list')
// push一个带有path属性的对象
router.push({path:'/list'})
}
</script>
<template>
<div>
<h1>App页面</h1>
<hr/>
<!-- 路由的连接 -->
<router-link to="/">home页</router-link> <br>
<router-link to="/list">list页</router-link> <br>
<!-- 动态输入路径,点击按钮,触发单击事件的函数,在函数中通过编程是路由切换页面 -->
<button @click="showList()">showList</button> <br>
<hr/>
<!-- 路由连接对应视图的展示位置 -->
<hr> 默认展示位置:<router-view></router-view>
<hr> Home视图展示:<router-view name="homeView"></router-view>
<hr> List视图展示:<router-view name="listView"></router-view>
</div>
</template>
<style scoped>
</style>
1.5 路由传参(useRoute)
路径参数:
- 在路径中使用一个动态字段来实现,我们称之为 路径参数:
- 例如: 查看数据详情
/showDetail/1,1就是要查看详情的id,可以动态添值。
- 例如: 查看数据详情
键值对参数:
类似与get请求通过url传参,数据是键值对形式的:
- 例如: 查看数据详情
/showDetail?hid=1,hid=1就是要传递的键值对参数。
- 例如: 查看数据详情
读取参数:
- 在 Vue 3 和 Vue Router 4 中,你可以使用
useRoute这个函数从 Vue 的组合式 API 中获取路由对象; useRoute方法返回的是当前的 route 对象,你可以用它来获取关于当前路由的信息,如当前的路径、键值对参数等;
案例需求 : 切换到ShowDetail.vue组件时,向该组件通过路由传递参数。
- 修改App.vue文件
<script setup type="module">
import {useRouter} from 'vue-router'
//创建动态路由对象
let router = useRouter()
//动态路由路径传参方法
let showDetail= (id,language)=>{
// 尝试使用拼接字符串方式传递路径参数
//router.push(`showDetail/${id}/${languange}`)
/*路径参数,需要使用params */
router.push({name:"showDetail",params:{id:id,language:language}})
}
let showDetail2= (id,language)=>{
/*uri键值对参数,需要使用query */
//router.push({path:`/showDetail2?id=${id}&language=${language}`)
router.push({path:"/showDetail2",query:{id:id,language:language}})
}
</script>
<template>
<div>
<h1>App页面</h1>
<hr/>
<!-- 路径参数 -->
<router-link to="/showDetail/1/JAVA">路径传参JAVA</router-link>
<button @click="showDetail(1,'JAVA')">编程式路由路径传参显示JAVA</button>
<hr/>
<!-- 键值对参数 -->
<router-link v-bind:to="{path:'/showDetail2',query:{id:1,language:'Java'}}">键值对传参JAVA</router-link>
<button @click="showDetail2(1,'JAVA')">编程式路由键值对传参JAVA</button>
<hr> showDetail视图展示:<router-view name="showDetailView"></router-view>
<hr> showDetail2视图展示:<router-view name="showDetailView2"></router-view>
</div>
</template>
<style scoped>
</style>- 修改router.js增加路径参数占位符
import {createRouter,createWebHashHistory} from 'vue-router'
import ShowDetail from '../components/ShowDetail.vue'
import ShowDetail2 from '../components/ShowDetail2.vue'
// 创建路由对象,声明路由规则
const router = createRouter({
history: createWebHashHistory(),
routes:[
{
/* 此处:id :language作为路径的占位符 */
path:'/showDetail/:id/:language',
/* 动态路由传参时,根据该名字找到该路由 */
name:'showDetail',
components:{
showDetailView:ShowDetail
}
},
{
path:'/showDetail2',
components:{
showDetailView2:ShowDetail2
}
},
]
})
// 对外暴露路由对象
export default router;- ShowDetail.vue 通过useRoute获取路径参数
<script setup type="module">
import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue';
// 获取当前的route对象
let route = useRoute()
let languageId = ref(0)
let languageName = ref('')
// 借助更新时生命周期,将数据更新进入响应式对象
onMounted(() => {
// 获取对象中的参数
languageId.value = route.params.id
languageName.value = route.params.language
console.log(languageId.value)
console.log(languageName.value)
})
</script>
<template>
<div>
<h1>ShowDetail页面</h1>
<h3>编号{{ route.params.id }}:{{ route.params.language }}是世界上最好的语言</h3>
<h3>编号{{ languageId }}:{{ languageName }}是世界上最好的语言</h3>
</div>
</template>
<style scoped></style>
- ShowDetail2.vue通过useRoute获取键值对参数
<script setup type="module">
import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue';
// 获取当前的route对象
let route = useRoute()
let languageId = ref(0)
let languageName = ref('')
// 借助更新时生命周期,将数据更新进入响应式对象
onMounted(() => {
// 获取对象中的参数(通过query获取参数,此时参数是key-value形式的)
console.log(route.query)
console.log(languageId.value)
console.log(languageName.value)
languageId.value = route.query.id
languageName.value = route.query.language
})
</script>
<template>
<div>
<h1>ShowDetail2页面</h1>
<h3>编号{{ route.query.id }}:{{ route.query.language }}是世界上最好的语言</h3>
<h3>编号{{ languageId }}:{{ languageName }}是世界上最好的语言</h3>
</div>
</template>
<style scoped></style>
1.6 路由守卫
在 Vue 3 中,路由守卫是用于在路由切换期间进行一些特定任务的回调函数。路由守卫可以用于许多任务,例如验证用户是否已登录、在路由切换前提供确认提示、请求数据等。Vue 3 为路由守卫提供了全面的支持,并提供了以下几种类型的路由守卫:
- 全局前置守卫:在路由切换前被调用,可以用于验证用户是否已登录、中断导航、请求数据等;
- 全局后置守卫:在路由切换之后被调用,可以用于处理数据、操作 DOM 、记录日志等;
- 守卫代码的位置: 在router.js中
//全局前置路由守卫
router.beforeEach( (to,from,next) => {
//to 是目标地包装对象 .path属性可以获取地址
//from 是来源地包装对象 .path属性可以获取地址
//next是方法,不调用默认拦截! next() 放行,直接到达目标组件
//next('/地址')可以转发到其他地址,到达目标组件前会再次经过前置路由守卫
console.log(to.path,from.path,next)
//需要判断,注意避免无限重定向
if(to.path == '/index'){
next()
}else{
next('/index')
}
} )
//全局后置路由守卫
router.afterEach((to, from) => {
console.log(`Navigate from ${from.path} to ${to.path}`);
});登录案例,登录以后才可以进入home,否则必须进入login。
- 定义Login.vue
<script setup>
// 导入动态路由跳转的相关方法
import { ref } from 'vue'
// 导入路由对象
import { useRouter, useRoute } from 'vue-router'
// 获取路由对象和路由信息
let router = useRouter('') // 用于跳转路由,传参
let route = useRoute('') // 用于获取路由信息,例如: 路径、参数
// 登录页面的用户名和密码
let username = ref('admin')
let password = ref('123456')
let login = () => {
if (username.value === 'admin' && password.value === '123456') {
// 登录成功,将登录状态存储到localStorage中
window.localStorage.setItem('username', username.value) // 全局有效 支持持久化 给成功页面显示欢迎信息使用
// 登录成功,跳转到首页
router.push('/home')
} else {
alert('用户名称或密码错误,请重新登录!')
}
}
</script>
<template>
<div>
<h1>登录页面</h1>
用户名称:<input type="text" v-model="username" placeholder="请输入用户名称"/>
<br />
密码:<input type="password" v-model="password" placeholder="请输入密码"/>
<br />
<button @click="login">登录</button>
</div>
</template>
<style scoped></style>- 定义Home.vue
<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
let router = useRouter('') // 用于跳转路由,传参
let username = ref('') // 用于显示欢迎信息
// 获取登录状态,用于显示欢迎信息
onMounted(() => {
username.value = window.localStorage.getItem('username') // 获取登录状态,用于显示欢迎信息
})
// 退出登录
let logout = () => {
// 清除localStorge中的username
window.localStorage.removeItem('username') // 清除登录状态
// 动态路由跳转到登录页面
router.push('/login')
}
</script>
<template>
<div>
<h1>首页</h1>
<h3>
欢迎您: {{ username }} 登录
</h3>
<button @click="logout">退出登录</button>
</div>
</template>
<style scoped></style>- App.vue
<script setup type="module">
</script>
<template>
<div>
<router-view></router-view>
</div>
</template>
<style scoped>
</style>- 定义routers.js
// 导入路由创建的相关方法
import { createRouter, createWebHistory } from 'vue-router'
// 导入vue组件
import Home from '../components/Home.vue'
import Login from '../components/Login.vue'
// 创建路由对象,声明路由规则
const router = createRouter({
history: createWebHistory(), // 记录历史路由跳转
// 配置路由规则
routes: [
{
path: '/home',
component: Home
},
{
path: '/',
redirect: '/home' // 重定向到home页面
},
{
path: '/login',
component: Login
},
]
})
// 设置路由的全局前置守卫
router.beforeEach((to, from, next) => {
if (to.path == '/login') {
next() // 放行
} else {
let username = window.localStorage.getItem('username') // 获取localStorage中的username
if (username != null) {
next() // 放行
} else {
next('/login') // 登录信息失效了,请重新登录
}
}
})
// 设置路由的全局后置守卫
router.afterEach((to, from) => {
console.log('从${from.path}来,到${to.path}去')
})
// 对外暴露路由对象
export default router- 启动测试
pnpm dev

