theme: smartblue
theme: smartblue
一、环境搭建
1.1 依赖下载
控制台输入npm install vue-router
1.2 注册路由服务
在 main.js 中添加路由信息
1.3 创建路由信息
``` // createRouter: 创建router实例对象 // createWebHashHistory: 创建history模式的路由 import { createRouter, createWebHistory } from "vue-router" import Login from '@/views/Login/index.vue' import Layout from '@/views/Layout/index.vue' import Home from "@/views/Home/index.vue" import Category from "@/views/Category/index.vue"
// 定义路由 const routers = [ { path:"/", component:Layout, children:[{ // 默认路由 path:"", component:Home },{ path:"category", component:Category }] },{ path:"/login", component:Login } ]
// 创建router实例 const router = createRouter({ history:createWebHistory(), routes:routers })
// 导出router实例 export default router
```
二、代码说明
2.1 一级路由
2.1.1 注册
Layout 和 Login 为一级路由
在 App.vue 中创建一级路由出口
2.1.2 效果演示
切换路由时,页面内容整体替换
2.2 二级路由
2.2.1 注册
Home 和 Category 为 Layout
下的子路由
在 Layout 下创建二级路由出口
2.2.2 效果演示
由于 Home 设置为了默认路由,所有会自动加载
切换路径后,Home页面的内容部分修改
三、路由传参
3.1 修改路由
将路由与动态id绑定
3.2 修改超链接
修改为动态的跳转链接:
<router-link :to="`/category/${item.id}`">{{ item.name }}</router-link>
3.3 设置跳转页面逻辑
3.4 效果演示
3.5 注意
3.5.1 问题描述
当不同id的分类连续调用时,组件不会触发onMounted事件,是因为vue默认的组件复用机制
3.5.2 解决策略一
可以为页面绑定唯一的key解决,
但是此种方案比较浪费性能,因为每次点击分类,都会重新加载资源
3.5.3 解决策略二
添加路由更新事件:
<template>
我是category内容页,加载的是id为【{{ route.params.id }}】的【{{page}}】页面
</template>
<script setup>
import {onMounted,ref} from "vue"
import {useRoute,onBeforeRouteUpdate} from 'vue-router'
const route = useRoute()
let page = ref()
// 目标: 路由参数变化时, 可以把分类下的分类数据接口重新发送
onBeforeRouteUpdate((to)=>{
console.log("路由切换了")
queryData(to.params.id)
})
onMounted(()=>{
console.log(route.params.id)
queryData()
})
function queryData(id = route.params.id){
if(id==1){
page.value = "居家"
}
if(id==2){
page.value = "美食"
}
if(id==3){
page.value = "服饰"
}
}
</script>
3.5.3.1 结构优化
对于数据获取的过程,可以额外封装到一个方法内
新建useCategory.js
:
import {onMounted,ref} from "vue"
import {useRoute,onBeforeRouteUpdate} from 'vue-router'
export function useCategory(){
// 分类名称
let page = ref()
// 分类id
let categoryId = ref()
const route = useRoute()
// 模拟数据库查询
const queryData = (id = route.params.id)=>{
categoryId.value = id
if(id==1){
page.value = "居家"
}
if(id==2){
page.value = "美食"
}
if(id==3){
page.value = "服饰"
}
}
// 路由参数变化时,把分类下的接口重新发送
onBeforeRouteUpdate((to)=>{
queryData(to.params.id)
})
onMounted(()=>{
console.log(route.params.id)
queryData()
})
return{
categoryId,
page
}
}
页面调用该封装的方法:
四、综合案例
4.1 需求
如图所示,现有两层目录结构:居家模块下有三个子模块,而这三个模块下又有独立的页面
4.2 创建sub路由
4.3 模拟一级目录数据
useCategory.js
``` import {onMounted,ref} from "vue" import {useRoute,onBeforeRouteUpdate} from 'vue-router'
export function useCategory(){
// 分类名称
let page = ref()
// 分类id
let categoryId = ref()
// 子页信息
let sub = ref()
const route = useRoute()
// 模拟数据库查询
const queryData = (id = route.params.id)=>{
categoryId.value = id
if(id==1){
page.value = "居家"
sub.value = [{
id:1,
name:"居家生活用品"
},{
id:2,
name:"收纳"
},{
id:3,
name:"宠物食物"
}]
}
if(id==2){
page.value = "美食"
sub.value = [{
id:1,
name:"南北干货"
},{
id:2,
name:"调味酱菜"
},{
id:3,
name:"方便食物"
}]
}
if(id==3){
page.value = "服饰"
sub.value = [{
id:1,
name:"钱包"
},{
id:2,
name:"靴子"
},{
id:3,
name:"运动鞋"
}]
}
}
// 路由参数变化时,把分类下的接口重新发送
onBeforeRouteUpdate((to)=>{
queryData(to.params.id)
})
onMounted(()=>{
console.log(route.params.id)
queryData()
})
return{
categoryId,
page,
sub
}
}
``
cetegory.vue`
`` <template> 我是category内容页,当前分类id为【{{ categoryId }}】 <div>【{{page}}】页的内容有:</div> <ul v-for="item in sub" :key="item.id"> <li> <router-link :to="
/category/sub/${item.id}`">{{ item.name }}
```
4.4 二级目录结构
参考 三、路由传参