包阅导读总结
1.
关键词:Vue 3、路由传参、Teleport、组件通信、全局状态管理
2.
总结:本文主要介绍了 Vue 3 中的路由传参(包括 Params 和 Query)以及 Teleport 组件的使用,还提及了组件通信和全局状态管理的相关内容。
3.
主要内容:
– Vue 3 通信
– 组件通信
– 全局状态管理(pinia、vuex)
– 路由传参
– Params 参数
– 通过路径一部分传递,用于动态部分
– 定义路由时在路径中使用占位符
– 导航到带参数路由使用 router.push 提供参数值
– Query 参数
– 通过 URL 中的查询字符串传递
– 无需修改目标页面路径格式,在当前页面使用 router.push 传递
– Teleport 组件
– 将组件渲染到 DOM 树中另一位置
– 处理模态框、弹窗等有用
– 以登录弹窗为例展示用法
– 解释为何在 app 内放置
思维导图:
文章地址:https://juejin.cn/post/7397292988672245775
文章来源:juejin.cn
作者:July_lly
发布时间:2024/7/30 12:58
语言:中文
总字数:1551字
预计阅读时间:7分钟
评分:78分
标签:Vue 3,Vue Router,路由传参,Teleport,组件通信
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
vue3通信大全(一)—— 组件通信与provide – 掘金 (juejin.cn)
vue3通信大全(三)—— 全局状态管理库pinia,vuex – 掘金 (juejin.cn)
vue3通信大全(四)—— Slot /浏览器储存/window – 掘金 (juejin.cn)
前言
在 Vue 3 中,除了传统的组件间通信方式(如 props 下传、事件上冒泡、Vuex 等),我们还可以利用路由来实现不同组件间的通信。下面我将详细介绍如何在 Vue 3 中使用路由传参以及一些相关的实践。
Params作为参数
Params
参数是通过路径的一部分来传递的,通常用于表示动态的部分,例如 /users/:userId
中的 :userId
就是一个 param
参数。
使用方法:定义路由:
在 Vue Router 中定义带有 params
的路由非常简单,只需要在路径中使用占位符即可:
index.js
文件中:
import { createWebHistory,createRouter } from "vue-router";const routes = [{ path: "/parent", name: "parent", component: () => import("@/components/demo2/parent.vue"), }, { path: "/child/:id", name: "child", component: () => import("@/components/demo2/child.vue"), }];const router = createRouter({ history: createWebHistory(), routes,});export default router;
当前页:
<template> <h1> 父组件 </h1><button @click="goSon">点击跳转</button> </template><script setup>import {useRouter} from 'vue-router'const router = useRouter()const goSon=()=>{ router.push({name:'child',params:{id: '123123'}})}</script>
目标页:
<template>son: route.params = {{ route.params.id }}</template><script setup>import {useRoute}from 'vue-router' const route = useRoute() </script>
当用户访问类似 /child/123
这样的 URL 时,:idd
的值会被自动提取出来,并且可以在这个组件中通过 route.params.id
获取到。而当我们如果需要从一个组件导航到另一个带有参数的路由,可以使用 router.push
方法,并且提供参数的值,从而实现传值。
Query 参数
Query
参数则是通过 URL 中的查询字符串来传递的,通常用于过滤、排序或者传递额外的信息,例如 /users?name=John
中的 name=John
就是一个 query
参数。
index
文件:
import { createWebHistory,createRouter } from "vue-router";const routes = [{ path: "/parent", component: () => import("@/components/demo2/parent.vue"), }, { path: "/child", component: () => import("@/components/demo2/child.vue"), }];const router = createRouter({ history: createWebHistory(), routes,});export default router;
当前页:
<template> <h1> 父组件 </h1><button @click="goSon">点击跳转</button> </template><script setup>import {useRouter} from 'vue-router'const router = useRouter()const goSon=()=>{ router.push({path:'/child',query:{id: '123123'}})}</script>
目标页:
<template>son: route.query.id = {{ route.query.id }}</template><script setup>import {useRoute}from 'vue-router'const route = useRoute()</script>
使用query传参时,不需要我们在路由文件中修改目标页面的path路径而格式,而是在当前页面使用router.push(path:'xxx',query:{键名:键值})
,在跳转到目标页面后,目标页面的url会在后面加上xxx?键名=键值
。而在目标页面要取到这个值,也是使用useRoute
获取到当前页面信息使用route.query.id
得到对应的query。
teleport
使用 Teleport
组件的主要目的是为了能够将一个组件渲染到 DOM 树中的另一个位置,而不是直接在其父组件的 DOM 子树内。这在处理模态框、弹窗等需要跨越多个组件层级的 UI 元素时特别有用。
非常好的例子就是登录弹窗的动态使用Teleport
来实现的,如果我们使用的是登入弹窗,那么不论在哪个页面,这个弹窗框的层级应该是最高的,同时应该脱离文档流不影响其下面的结构。我们在HTML中会使用Z-index属性,但是在vue组件化结构中是不生效的,因此Teleport
便孕育而生。
index.html
文件:
<div id="app"> <App></App> </div> <div id="login-container"></div>
App.vue
文件:
<template> <div> <button @click="showLogin = true">Login</button> 这是之外的数据 <teleport v-if="showLogin" to="#login-container"> <div class="login-modal"> <h1>登入</h1> <input type="text" placeholder="Username" v-model="username"> <input type="password" placeholder="Password" v-model="password"> <button @click="submitLogin">提交</button> </div> </teleport> </div></template><script setup>import{ref}from 'vue' const showLogin=ref(false) const username=ref('') const password=ref('') const submitLogin=()=>{ showLogin.value = false; }</script>
这里我们明显看到登入框弹出时,taleport并没有挤压其他的DOM结构。
为什么需要在#app内再放一个<App />
?
- 分离关注点:
<App>
元素允许我们在 HTML 文件中定义应用程序的主要内容区域,而main.js
中的app.mount('#app')
则负责将 Vue 组件挂载到这个区域。
- 保持 HTML 结构清晰:
- 通过在 HTML 中定义
<App>
,我们可以保留 HTML 文件的基本结构,使其易于阅读和维护。
- 通过在 HTML 中定义
换句话说我们也可以在#app
内再放一个<App />
但是这样做使得我们的登入的DOM结构不再清晰,这时不被优秀的程序设计所接受的。