18_Vue3路由机制

embedded/2024/9/25 4:56:17/

Vue3路由机制router

1 路由简介

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

  • 通俗理解:路由就像是一个地图,我们要去不同的地方,需要通过不同的路线进行导航。

2 路由的作用

  • 单页应用程序(SPA)中,路由可以实现不同视图之间的无刷新切换,提升用户体验;
  • 路由还可以实现页面的认证和权限控制,保护用户的隐私和安全;
  • 路由还可以利用浏览器的前进与后退,帮助用户更好地回到之前访问过的页面。

2 路由入门案例

1 案例需求分析

在这里插入图片描述

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

npm create vite //创建项目cd 项目文件夹 //进入项目文件夹
npm install //安装项目需求依赖
npm install vue-router@4 --save //安装全局的vue-router 4版本

3 准备页面和组件

  • 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>
<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>

4 准备路由配置

  • 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 中,//使用 createWebHashHistory() 方法,可以创建一个路由历史记录对象,用于管理应用程序的路由。在 Vue.js 应用中,//通常使用该方法来创建路由的历史记录对象。//就是路由中缓存历史记录的对象,vue-router提供history: createWebHashHistory(),routes:[{path:'/',/* component指定组件在默认的路由视图位置展示components:Homecomponents指定组件在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;

5 main.js引入router配置

  • 修改文件:main.js (入口文件)
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
//导入router模块
import router from './routers/router.js'
let app = createApp(App)
//绑定路由对象
app.use(router)
//挂在试图
app.mount("#app")

6 启动测试

npm run dev

3 路由重定向

重定向的作用:将一个路由重定向到另一个路由上

  • 修改案例:访问/list和/showAll都定向到List.vue
  • 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({history: createWebHashHistory(),routes:[{path:'/',components:{default:Home,homeView:Home}      },{path:'/list',components:{listView : List} },{path:'/showAll',// 重定向redirect :'/list'},{path:'/add',components:{addView:Add} },{path:'/update',components:{updateView:Update}  },]})// 对外暴露路由对象
export default router;
<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>

4 编程式路由(useRouter)

普通路由

  • <router-link to="/list">list页</router-link> 这种路由,to中的内容目前是固定的,点击后只能切换/list对象组件(声明式路由)

编程式路由

  • 通过useRouter,动态决定向那个组件切换的路由
  • 在 Vue 3 和 Vue Router 4 中,你可以使用 useRouter 来实现动态路由(编程式路由)
  • 这里的 useRouter 方法返回的是一个 router 对象,你可以用它来做如导航到新页面、返回上一页面等操作。

案例需求: 通过普通按钮配合事件绑定实现路由页面跳转,不直接使用router-link标签

<script setup type="module">import {useRouter} from 'vue-router'import {ref} from 'vue'//创建动态路由对象let router = useRouter()let  routePath =ref('')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><router-link to="/showAll">showAll页</router-link> <br><router-link to="/add">add页</router-link> <br><router-link to="/update">update页</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><hr>Add视图展示:<router-view name="addView"></router-view><hr>Update视图展示:<router-view name="updateView"></router-view></div>
</template><style scoped>
</style>

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",query:{id:id,language:language}})}
</script><template><div><h1>App页面</h1><hr/><!-- 路径参数   --><router-link to="/showDetail/1/JAVA">showDetail路径传参显示JAVA</router-link> <button @click="showDetail(1,'JAVA')">showDetail动态路由路径传参显示JAVA</button><hr/><!-- 键值对参数 --><router-link v-bind:to="{path:'/showDetail2',query:{id:1,language:'Java'}}">showDetail2键值对传参显示JAVA</router-link> <button @click="showDetail2(1,'JAVA')">showDetail2动态路由键值对传参显示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'// 导入vue组件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 { onUpdated,ref } from 'vue';// 获取当前的route对象let route =useRoute()let languageId = ref(0)let languageName = ref('')//  借助更新时生命周期,将数据更新进入响应式对象onUpdated (()=>{// 获取对象中的参数languageId.value=route.params.idlanguageName.value=route.params.languageconsole.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 { onUpdated,ref } from 'vue';// 获取当前的route对象let route =useRoute()let languageId = ref(0)let languageName = ref('')//  借助更新时生命周期,将数据更新进入响应式对象onUpdated (()=>{// 获取对象中的参数(通过query获取参数,此时参数是key-value形式的)console.log(route.query)console.log(languageId.value)console.log(languageName.value)languageId.value=route.query.idlanguageName.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>

6 路由守卫

在 Vue 3 中,路由守卫是用于在路由切换期间进行一些特定任务的回调函数。路由守卫可以用于许多任务,例如验证用户是否已登录、在路由切换前提供确认提示、请求数据等。Vue 3 为路由守卫提供了全面的支持,并提供了以下几种类型的路由守卫:

  1. 全局前置守卫:在路由切换前被调用,可以用于验证用户是否已登录、中断导航、请求数据等。
  2. 全局后置守卫:在路由切换之后被调用,可以用于处理数据、操作 DOM 、记录日志等。
  3. 守卫代码的位置: 在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} 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)//sessionStorage.setItem('username',username)}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>
<script setup>import {ref} from 'vue'import {useRoute,useRouter} from 'vue-router'let route =useRoute()let router = useRouter()//  并不是每次进入home页时,都有用户名参数传入//let username = route.query.usernamelet username =window.localStorage.getItem('username'); let logout= ()=>{// 清除localStorge中的username//window.sessionStorage.removeItem('username')window.localStorage.removeItem('username')// 动态路由到登录页router.push("/login")}</script><template><div><h1>Home页面</h1><h3>欢迎{{username}}登录</h3><button @click="logout">退出登录</button></div>
</template><style scoped></style>
<script setup type="module"></script><template><div><router-view></router-view></div>
</template><style scoped>
</style>
  • 定义routers.js
// 导入路由创建的相关方法
import {createRouter,createWebHashHistory} from 'vue-router'// 导入vue组件import Home from '../components/Home.vue'
import Login from '../components/login.vue'
// 创建路由对象,声明路由规则
const router = createRouter({history: createWebHashHistory(),routes:[{path:'/home',component:Home},{path:'/',redirect:"/home"},{path:'/login',component:Login},]})// 设置路由的全局前置守卫
router.beforeEach((to,from,next)=>{/* to 要去那from 从哪里来next 放行路由时需要调用的方法,不调用则不放行*/console.log(`从哪里来:${from.path},到哪里去:${to.path}`)if(to.path == '/login'){//放行路由  注意放行不要形成循环  next()}else{//let username =window.sessionStorage.getItem('username'); 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;
  • 启动测试
npm run dev


http://www.ppmy.cn/embedded/47350.html

相关文章

Spring IoC注解

一、回顾反射机制 反射的调用三步&#xff1a;1&#xff09;获取类。2&#xff09;获取方法。3&#xff09;调用方法 调用方法&#xff1a;调用哪个对象&#xff0c;哪个方法&#xff0c;传什么参数&#xff0c;返回什么值。 方法&#xff08;Do&#xff09;类&#xff1a; …

Django render()函数页面渲染

1&#xff0c; render() 函数 在Django框架中&#xff0c;render() 函数是一个非常有用的快捷方式&#xff0c;用于从视图函数返回一个完整的HTTP响应。它负责将给定的模板与上下文数据结合&#xff0c;渲染出最终的HTML页面&#xff0c;并返回一个HttpResponse对象。 from d…

【JVM】之常见面试题

文章目录 1.JVM中的内存区域划分2.JVM的类加载机制2.1 加载2.2 验证2.3 准备2.4 解析2.5 初始化2.6 类加载的时机 3 类加载器4.双亲委派模型5.JVM中的垃圾回收策略5.1 找谁是垃圾5.1.1 引用计数法5.1.2 可达性分析法 5.2 释放垃圾5.2.1 标记清除算法5.2.2 复制算法5.2.3 标记整…

CANopen for Python 使用教程(二)

系列文章目录 前言 CANopen 标准的 Python 实现。该项目的目的是在一个简单的 Pythonic 接口中支持 CiA 301 标准中最常见的部分。它主要针对测试和自动化任务&#xff0c;而不是符合标准的主实施。 该库支持 Python 3.6 及以上版本。 一、特点 该库主要用作主库。 NMT 主站…

freebsd 14.1 简易安全安装步骤

下面安装在真机上进行&#xff0c;安装的是KDE界面&#xff0c;virtual box虚拟机上安装&#xff0c;安装前设置中显示改为VBoxSVGA&#xff0c;缩放设置为150%要不然安装后界面文字非常小看不见&#xff0c;其他基本一样。 总结出来的简易安全快速安装步骤方法&#xff1a; …

iOS swift5 加载网络图片的第三方框架

Kingfisher - github: 类似SDWebImage 参考博客&#xff1a; 一些swift项目中常用的处理图片的第三方框架 - 博客园

Java爬虫——正则表达式应用

Pattern Matcher均属于regex下 步骤&#xff1a;pattern获取正则&#xff0c;matcher获取文本对象&#xff0c;find截取字符串&#xff08;返回true、false&#xff09;&#xff0c;group获得字符 例题&#xff1a;爬取指定文字 分析&#xff1a; 二次调用时&#xff1a; 循环…

项目问题24/5/29需求:用一路IO口捕获外界方波PWM频率,将捕获值实时传入,使得正弦波频率和外界方波频率一致

问题 STM32F103控制下,定时器3的捕获PWM模式下的中断里的全局变量psc 20,中断触发后&#xff0c;主函数while循环里TIM1_PWM_Init(1451,psc)函数初始化正弦波&#xff0c;用了中断传过来的全局变量psc后&#xff0c;为什么PWM频率不是PWM 72000000.0 / ((145 * (psc11))24.8…