当前位置: 首页 > news >正文

Javaweb - 14.5 Vue3 路由机制

目录

路由简介

路由入门案例

编程式路由(useRouter)

路由传参(useRoute)

路由守卫

案例测试

完!


路由简介

什么是路由:

        定义:路由就是根据不同的 URL 地址展示不同的内容或页面

作用:

        SPA 中,可以实现不同视图之间的无刷新切换

        实现页面认证和权限控制

路由入门案例

案例需求:

创建项目和导入路由依赖:

npm create vite@4 

npm install

npm install vue-router@4 --save

准备页面组件

单独在 src 文件夹下面创建一个 routers 文件夹,里面存放 router.js

// 导入创建路由对象需要的函数
import {createRouter,createWebHashHistory} from 'vue-router'// 导入 .vue 组件
import Home from '../comments/Home.vue'
import List from '../comments/List.vue'
import Add from '../comments/Add.vue'
import Update from '../comments/Update.vue'// 创建一个路由对象
const router = createRouter({// history 属性用于记录路由的历史history:createWebHashHistory(),// routes 用于定义多个不同的路径和组件之间的对应关系routes:[{path:'/home',component:Home},{path:'/list',component:List},{path:'/add',component:Add},{path:'/update',component:Update},{path:'/',component:Home}]
})// 向外暴露
export default rouer

配置 main.js 文件:

import { createApp } from 'vue'import App from './App.vue'
// 在整个 App.vue 中可以使用路由
import router from './routers/router.js'const app = createApp(App)
// 绑定路由对象
app.use(router)
// 挂载视图
app.mount('#app')

App.vue 的页面

<script setup>
</script><template><div>App 开头的内容 <br><router-link to = "/Home">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><!-- router-view 标签会背替换成具体的 .vue --><router-view></router-view><hr>App 结束的内容</div>
</template><style scoped></style>

这样,就基础的实现了我们的需求:

我们还可以在不同的页面中进行相互跳转:

例如,在 Home 页中同样加一个 router-link 标签,实现从 Home 页向 Add 页的跳转:

<script setup>
</script><template><div><router-link to="/add">Add页</router-link><h1> Home 页面</h1></div>
</template><style scoped></style>

也可以实现重定向,比如当我们的路径为 /showAll 的时候,重定向到 /list:

先在 router.js 中的 router 对象中,配置 path 和对应的 redirect

然后在 App.vue 中添加 router-link 的标签即可

编程式路由(useRouter)

声明式路由:

<router-link to = "/list">list页</router-link> 这种路由,点击后只能切换 /list 对应的组件,是固定的

编程式路由:

通过 useRouter,动态决定向那个组件切换的路由

这里的 useRouter 方法返回的是一个 router 对象,可以用它来做,如导航到新页面,返回上一面等操作

<script setup>import {useRouter} from 'vue-router'import {ref} from 'vue'let myPath = ref('')const router = useRouter()function showList() {// 编程式路由实现页面跳转// 方式一:router.push("/list")router.push({path:"/list"})}function goMyPage() {router.push(myPath.value)}
</script><template><div><!-- 声明式路由 --><router-link to="/home">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><!-- 编程式路由 --><button @click="showList()">list</button><br><button @click="goMyPage()">Go</button><input type = "text" v-model="myPath"><router-view></router-view></div>
</template><style scoped></style>

路由传参(useRoute)

路径参数:

        在路径中使用一个动态字段来实现,我们称之为路径参数。

        例如:查看数据详情 /showDetail/1, 1 就是要查看详情的 id,可以动态填值。

键值对参数:

        类似与 get 请求通过 URL 传参,数据是键值对形式的。

        例如:查看数据详情 /showDetail?hid=1,hid 就是要传递的键值对参数。

读取参数:

在 Vue3 和 Vue Router4 中,我们可以使用 useRoute 这个函数,从 Vue 的组合式 API 中获取路由对象。

useRoute 方法返回的是当前的 route 对象,我们可以用它来获取关于当前路由的信息,如当前的路径,键值对参数等。


案例需求:切换到 ShowDetail.vue 组件时,向该组件通过路由传递参数


1.路径参数:{声明式路由和编程式路由}

准备一个 ShowDetail.vue 页面:

<script setup></script><template><div><h1>ShowDetail接收路径参数</h1></div>
</template><style scoped></style>

在 router.js 中进行配置:

// 导入创建路由的相关方法
import { createRouter, createWebHashHistory } from "vue-router";// 导入 .vue 组件
import Home from '../components/Home.vue'
import Add from '../components/Add.vue'
import List from '../components/List.vue'
import Update from '../components/Update.vue'
import ShowDetail from '../components/ShowDetail.vue'const router = createRouter({history:createWebHashHistory(),routes:[{path:"/showDetail/:id/:language",component:ShowDetail},{path:"/",component:Home,},{path:"/home",component:Home,},{path:"/list",component:List,},{path:"/add",component:Add,},{path:"/update",component:Update}]
})
export default router

ShowDetail.vue:

<script setup>
/*** 接收传递过来的路径参数* useRoute 函数是用来接收参数的*/import {useRoute} from 'vue-router'import {ref,onUpdated} from 'vue'let languageId = ref(0)let languageName = ref("")let route = useRoute()languageId.value=route.params.idlanguageName.value=route.params.language// 让页面可以实时更新~onUpdated(()=>{languageId.value=route.params.idlanguageName.value=route.params.language})
</script><template><div><h1>ShowDetail接收路径参数</h1><h3>{{languageId}}{{languageName}}是世界上最好的语言</h3></div>
</template><style scoped></style>

App.vue:

<script setup>import {useRouter} from 'vue-router'import {ref} from 'vue'const router = useRouter()function showDetail(id,language){router.push(`/showDetail/${id}/${language}`)}
</script><template><div><router-link  to="/showDetail/1/java">声明式路由路径传参</router-link><button @click="showDetail(2,'PHP')">编程式路由路径传参</button><hr><router-view></router-view></div>
</template><style scoped></style>

2. 键值对参数{声明式路由和编程式路由}

router.js:

// 导入创建路由的相关方法
import { createRouter, createWebHashHistory } from "vue-router";// 导入 .vue 组件
import Home from '../components/Home.vue'
import Add from '../components/Add.vue'
import List from '../components/List.vue'
import Update from '../components/Update.vue'
import ShowDetail from '../components/ShowDetail.vue'
import ShowDetail2 from '../components/showDetail2.vue'
const router = createRouter({history:createWebHashHistory(),routes:[{path:"/showDetail2",component:ShowDetail2},{path:"/showDetail/:id/:language",component:ShowDetail},{path:"/",component:Home,},{path:"/home",component:Home,},{path:"/list",component:List,},{path:"/add",component:Add,},{path:"/update",component:Update}]
})
export default router

ShowDetail2:

<script setup>
/*** 接收传递过来的路径参数* useRoute 函数是用来接收参数的*/import {useRoute} from 'vue-router'import {ref,onUpdated} from 'vue'let languageId = ref(0)let languageName = ref("")let route = useRoute()languageId.value=route.query.idlanguageName.value=route.query.languageonUpdated(()=>{languageId.value=route.query.idlanguageName.value=route.query.language})
</script><template><div><h1>ShowDetail2接收键值对参数</h1><h3>{{languageId}}{{languageName}}是世界上最好的语言</h3></div>
</template><style scoped></style>

App.vue:

<script setup>import {useRouter} from 'vue-router'import {ref} from 'vue'const router = useRouter()function showDetail(id,language){router.push(`/showDetail/${id}/${language}`)}function showDetail2(id,language){router.push(`/showDetail2?id=${id}&language=${language}`)}
</script><template><div><router-link to ="/showDetail2?id=1&language=java">声明式路由键值对传参</router-link><button @click="showDetail2(2,'PHP')">编程式路由键值对传参</button><hr><router-view></router-view></div>
</template><style scoped></style>

路由守卫

在 Vue3 中,路由首位是用于在路由切换期间,进行一些特定任务的回调函数。路由守卫可以用于许多任务:例如验证用户是否已经登录,在路由切换前提供确认提示,请求数据等。

        全局前置守卫:在路由切换前被调用,可以用于验证用户是否已登录,中断导航,请求数据等。

        全局后置首位:在路由切换之后被调用,可以用于处理数据,操作 DOM,记录日志等

        守卫代码的位置:在 router.js 文件中

// 设置全局前置首位
// 每次路由切换页面前,都会执行 beforeEach 中的回调函数
router.beforeEach((to,from,next)=>{/*** from 上一个页面 表示从哪里来* to 下一个页面 表示到哪里去* next 放行的方法,只有执行了该方法,才会放行路由 类似与过滤器中的 filterChain.doFilter* next() 放行* next("/路径") 路由的重定向,可以转发到其他地址* 但是到达目标组件前会在此经过前置路由守卫,需要注意判断,避免无限重定向* * */console.log("beforeEach")console.log(from.path)console.log(to.path)next()}
)
// 设置全局后置路由
// 每次路由切换页面后,都会执行 afterEach 中的回调函数
router.afterEach(()=>{console.log("afterEach")}
)

案例测试

要求:登录案例,登录以后才可以进入 home 页面,否则必须进入 login 页面

Login.vue:

<script setup>import {ref} from 'vue'import {useRouter} from 'vue-router'let username = ref('')let password = ref('')let router = useRouter()let login = () => {console.log(username.value, password.value)if (username.value == 'root' && password.value == '123456') {router.push({path:'/home',query:{'username':username.value}})// 登录成功利用前端存储机制,存储账号localStorage.setItem('username', username.value)} else {alert("登陆失败,账号或密码错误")}}
</script><template><div>账号:<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} from 'vue'import {useRouter, useRoute} from 'vue-router'let route = useRoute()let router = useRouter()let username = window.localStorage.getItem('username')let logout = () => {//清楚 localStorge 中的 usernamewindow.localStorage.removeItem('username')// 动态路由到登录页router.push('/login')}
</script><template><div><h1> Home 页面</h1><h3>欢迎{{username}}登录</h3><button @click="logout()">退出登录</button></div>
</template><style scoped>
</style>

App.vue:

<script setup></script><template><div><router-view></router-view></div>
</template><style scoped>
</style>

定义 routers.js:

import { createRouter, createWebHashHistory } from "vue-router";
import Home from "../components/Home.vue";
import Login from "../components/Login.vue";const router = createRouter({history: createWebHashHistory(),routes: [{path: "/home",component: Home,},{path:"/",component:Home},{path:"/login",component:Login}],
});// 设置路由的全局前置首位
router.beforeEach((to,from,next) => {console.log(`从哪里来:${from.path},到哪里去${to.path}`)if (to.path == '/login') {next()} else {let username = window.localStorage.getItem("username")if (null != username) {next()} else {next("/login")}}}
)// 设置路由的全局后置首位
router.afterEach((to, from) => {console.log(`从哪里来:${from.path},到哪里去${to.path}`)}
)// 对外暴露路由对象
export default router

修改 main.js

import { createApp } from 'vue'
import App from './App.vue'import router from './routers/router'
let app = createApp(App)
app.use(router)
app.mount('#app')

测试无误~

补充:

路由传参:useRoute,编程式路由:useRouter:

完!


文章转载自:

http://uY0OiKiw.xctdn.cn
http://4JTmm7MR.xctdn.cn
http://8g1Xr9sc.xctdn.cn
http://jJef9y0w.xctdn.cn
http://z6MzL3E5.xctdn.cn
http://5HDdJZFK.xctdn.cn
http://Au3g7MFp.xctdn.cn
http://vTpo1pia.xctdn.cn
http://KSbvkRZs.xctdn.cn
http://xbW8bCzU.xctdn.cn
http://5u7g7gId.xctdn.cn
http://q2TRip2I.xctdn.cn
http://aPpjAzTQ.xctdn.cn
http://WwOLpqkQ.xctdn.cn
http://RiDBSg21.xctdn.cn
http://CTv0PeXu.xctdn.cn
http://BoN1SD60.xctdn.cn
http://G5zoQAJx.xctdn.cn
http://tqn5K1y9.xctdn.cn
http://sLF1moBB.xctdn.cn
http://Rf4BQuVP.xctdn.cn
http://QkKnlOeE.xctdn.cn
http://3ukWzBe8.xctdn.cn
http://dOtH2XkD.xctdn.cn
http://i8bSqjmO.xctdn.cn
http://oMQ6EKaf.xctdn.cn
http://vcNYOpg4.xctdn.cn
http://JW9GTHMY.xctdn.cn
http://hhAAfRu9.xctdn.cn
http://7EzS1i6o.xctdn.cn
http://www.dtcms.com/a/372343.html

相关文章:

  • 2.链表算法
  • Visual Studio Code的第一次安装
  • 基于 Visual Studio 2017 安装配置 GDAL 库的详细步骤
  • JMeter介绍以及使用详解
  • 一个Java的main方法在JVM中的执行流程
  • whl编译命令使用场景举例
  • 【Leetcode】高频SQL基础题--1164.指定日期的产品价格
  • 力扣1210. 穿过迷宫的最少移动次数 详解
  • Redis 从入门到精通:全平台安装与性能优化配置指南
  • RestClient查询和数据聚合
  • 前后端中的回调机制:含义、作用与实现详解
  • 四、神经网络的学习(下)
  • 万字详解网络编程之socket
  • PNG和JPEG和BMP文件格式转换
  • 语音之战+通用大模型,AI霸权决战打响
  • eslint 和 prettier 的相同点和区别
  • 苹果 FoundationModels 秘典侠客行:隐私为先的端侧 AI 江湖
  • hot100链表类题目
  • 算法:链表
  • Vscode中开发VUE项目的调试方案
  • Lua > OpenResty HelloWorld
  • FreeRTOS项目(2)摇杆按键检测
  • 《一往无前:雷军亲述小米热血 10 年》(上部)读书笔记
  • 线性代数 | 行图像 / 列图像
  • 【PCIe EP 设备入门学习专栏 -- 8.2.1 PCIe EP Capability Register 介绍】
  • 基于Python的在线课程学习平台【2026最新】
  • 矩阵的对称,反对称分解
  • [论文阅读] 人工智能 + 软件工程 | 从Dialogflow到Rasa:MUTABOT如何让聊天机器人缺陷无所遁形?
  • 视频软件 SMPLAYER
  • AutoGPT实战体验:AI自动任务工具如何高效完成深度调研?避坑技巧分享