总结 Vue3 的 13 种传参通信方式,非常齐全!!!

目录

一、父传子

二、子传父

三、兄弟组件传参(mitt)

 四、$attrs

五、refs传参

六、v-model

八、路由传参

九、vuex 传参 / pinia

十、浏览器缓存

十一、通过window对象全局挂载全局对象或者属性

十二、app.config.globalProperties


在前端项目离不开的传参通信方式,今天总结关于 Vue3 的传参方式如下:

  1. props 父传子
  2. defineEmits 子传父
  3. mitt 兄弟组件传参
  4. $attrs (爷孙)
  5. refs
  6. v-model (双向)
  7. provide/inject (多层)
  8. 路由传参
  9. vuex 传参 (全局)
  10. pinia 传参 (全局)
  11. 浏览器缓存 (全局)
  12. window (全局)
  13. app.config.globalProperties (全局)

一、父传子

 思路:父组件通过冒号:绑定变量,然后子组件用 const props = defineProps({}) 进行接收参数。

 父组件代码: 在第二行那里 :name="name"  把那么传给子组件

<template>
  <child :name="name"></child>
</template>

<script setup>
import { ref } from 'vue'
import child from './child.vue'

const name = ref('天天鸭')
</script>

子组件代码: const props = defineProps ({}) 接收后直接在标签使用

<template>
  <div>{
  
  { props.name }}</div>
</template>

<script setup>
import { defineProps } from 'vue'
const props = defineProps({
  name: {
    type: String,
    default: '',
  },
})
</script>

二、子传父

思路:子组件用 const emits = defineEmits( ['触发的方法'] )  注册某个在父组件的事件,然后通过 emits ( '触发的事件', 参数 ) 触发父组件事件并且带上参数。

 子组件代码: 注册 addEvent 事件后, 用 emits('addEvent', name.value) 触发父组件的 addEvent事件

<template>
  <div ></div>
</template>

<script setup>
import { ref, defineEmits } from 'vue'

const name = ref('天天鸭')
const emits = defineEmits(['addEvent'])
const handleSubmit = () => {
  emits('addEvent', name.value)
}
</script>

父组件代码: 触发 addEvent 事件后,在对应的方法里面直接能拿到传过来的参数

<template>
  <child @addEvent="handle"></child>
</template>

<script setup>
import { ref } from 'vue'
import child from './child.vue'

const handle = value => {
  console.log(value); // '天天鸭'
}
</script>

三、兄弟组件传参(mitt)

以前 vue2 是用 EventBus 事件总线跨组件实现兄弟组件通信的。但 vue3 中没有,所以 vue3 目前主流使用 mitt.js 插件来进行替代实现兄弟通信。

 1、npm 包引入

 npm install --save mitt

2、在 main.js 文件进行全局挂载, $bus 是自定义属性名

import mitt from "mitt"

const app = createApp(App)

app.config.globalProperties.$bus = new mitt()

3、传参出去的兄弟组件代码

<script setup>
    import mitt from 'mitt'
    const emitter = mitt()
    emitter.emit('自定义的事件名称','参数')
</script>

4、接收参数的兄弟组件代码

<script setup>
     import mitt from 'mitt'
     const emitter = mitt()
     emitter.on('自定义的事件名称', '参数' )
</script>

 四、$attrs

注意: 以前在在 vue2 里面中除了 $attrs,还有 $listeners ; 但 vue3 直接把 $listeners 合并到 $attrs 里面了。

 简要说明:$attrs 主要作用是接收没在 props 里面定义,但父组件又传了过来的属性。看下面代码例子就好懂多了

父组件代码: 传两个属性过去,一个在子组件 props 中,一个不在 

<template>
  <child :name="天天鸭" data="PC9527"/>
</template>

<script setup>
import child from './child.vue'
</script>

子组件代码$attrs 接收到 props 以外的内容,所以用 useAttrs() 打印出来没有 name 只有 data

<template>
  <div>
  {
  
  { props.name }}   // '天天鸭'
  </div>
</template>

<script setup>
import { defineProps, useAttrs } from 'vue'
const props = defineProps({
  name: {
    type: String
  }
})

const myattrs = useAttrs()
console.log(myattrs)   //  { "data": "PC9527" }
</script>

五、refs传参

简单说明:父组件通过在子组件上定义 ref='ref 名称',然后 const ref名称 = ref(null),就能通过 ref 名称操控子组件的属性和方法(子组件用 defineExpose 对外暴露才能被操控),具体看下面例子。

父组件代码: 

<template>
  <child ref="myref"></child>
  <button @click="myClick">点击</button>
</template>

<script setup>
  import child from "./child.vue"
  import { ref } from "vue"
  const myref = ref(null)
  const myClick = () => {
      console.log(myref.value.name) // 直接获取到子组件的属性
      myref.value.chileMethod()      // 直接调用子组件的方法
  }
</script>

子组件代码: defineExpose 对外暴露才能被操控

<template>
  <div></div>
</template>

<script setup>
    import { defineExpose } from "vue"

    const chileMethod = () =>{
      console.log("我是方法")
    }
    const name = ref('天天鸭')

    defineExpose({    // 对外暴露
        name,
        chileMethod
    })
</script>

六、v-model

简单讲解: v-model 其实语法糖,如下两行代码作用是一样, 上面是下面的简写。

<chile v-model:title="title" />

<chile :title="title" @update:title="title = $event" />

 父组件代码: 直接使用 v-model 传参

<template>
  <child v-model:name="name" v-model:num="num"></child>
</template>

<script setup>
    import child from "./child.vue"
    import { ref, reactive } from "vue"
    const name = ref("天天鸭")
    const num = ref("2222")
</script>

子组件代码: 通过 defineEmits 获取到然后用 emit ( "update: 修改的属性", 修改的内容 ) 进行修改父组件的内容,注意:update: 是固定写法。

<template>
  <button @click="myClick">点击</button>
</template>

<script setup>
  import { defineEmits } from "vue"
  const emit = defineEmits(["name","num"])
  
  // 子组件触发使用
  const myClick = () => {
      emit("update:name", "改个新名字")
      emit("update:num", "换个新号码")
  }
</script>

v-model扩展:defineModel():

defineModel() 宏的简单说明:父子组件的数据双向绑定,不用 emit 和 props 的繁重代码

版本要求:必须要 3.4+

 示例场景:父组件引入一个子组件弹窗,点击就父传子( props )弹出子组件弹窗,子组件里面有个按钮点击就子传父( emit )关闭

 父组件代码: v-model 在子组件身上绑定 showDevice 属性,该属性用于通知子组件是否打开弹窗。

<template>
  <child v-if="showDevice" v-model="showDevice"></child>
</template>

<script setup>
    import child from "./child.vue"
    import { ref } from "vue"
    
    const showDevice = ref(false) // 控制子组件的显示和隐藏
</script>

子组件代码: 如下的 handleClickCancel 方法,通过 defineModel 宏声明一个 model,点击按钮能直接通知父组件修改属性。

<template>
  <button @click="handleClickCancel">点击取消子组件弹窗</button>
</template>

<script setup>
  import { defineModel } from 'vue'
  const model = defineModel()                       // 写法一
  // const model = defineModel({ type: Boolean })   // 写法二 也可以用声明类型的方法

  const handleClickCancel = () => {
    model.value = false
  }
</script>

上面例子通过 defineModel 宏,直接不需要 props 和 emit 就实现了父子通信效果,非常简洁好用。

七、provide/inject

简单讲解:provideinject 叫依赖注入,是 vue 官方提供的 API,它们可以实现多层组件传递数据,无论层级有多深,都可以通过这 API 实现。

假设这是太老爷组件: provide ( '名称', 传递的参数 ) 向后代组件提供数据, 只要是后代都能接收

<template>
  <div></div>
</template>

<script setup>
import { ref, provide } from 'vue'
const name = ref('天天鸭')
// 向后代组件提供数据, 只要是后代都能接收
provide('name', name.value)
</script>

最深层的孙组件: 无论层级多深,用 inject ( 接收什么参数 ) 进行接收即可

<template>
  <div>{
  
  { name }}</div>
</template>

<script setup>
import { inject } from 'vue'
// 接收顶层组件的通信
const name = inject('name')
</script>

八、路由传参

简单讲解: 路由跳转事上参数也是传参的一种,而且传参方式还不止一种呢,下面细说。

1、query传参

// 传递方
const query = { id: 9527, name: '天天鸭' }
router.push({ path: '/user', query })

// 接收方
import { useRoute} from 'vue-router'
const route = useRoute()
console.log(route.query)

 2、params传参

注意:4.1.4 (2022-08-22) 删除了 param 这种方式

// 发送方
router.push({
   name: 'test', 
   params: {
       name: '天天鸭'
   }
})
 
// 接收方
import { useRoute} from 'vue-router'
const route = useRoute()
console.log(route.params) // { name: '天天鸭' }

 3、state 传参

// 发送方
const state= { name: '天天鸭' }
router.push({ path: '/user', state })
 
// 接收方直接使用
console.log(history?.state?.name)

九、vuex 传参 / pinia

写过对应的文章,可以直接细看:对比 vuex 和 pinia

https://juejin.cn/post/7355050145485914149

十、浏览器缓存

localStoragesessionStorage: 这算是用的不多,但也是必用的一种通信方式了,下面看看区别:

sessionStorage(临时存储):为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载

localStorage(长期存储):与 sessionStorage 一样,但是浏览器关闭后,数据依然会一直存在

 下面直接上使用的语法。

// 存储数据
localStorage.setItem('key', 'value');
sessionStorage.setItem('key', 'value');

// 获取数据
const valueFromLocalStorage = localStorage.getItem('key');
const valueFromSessionStorage = sessionStorage.getItem('key');

// 删除数据
localStorage.removeItem('key');
sessionStorage.removeItem('key');

// 清空所有数据
localStorage.clear();
sessionStorage.clear();

十一、通过window对象全局挂载全局对象或者属性

简单说明:直接用语法 window.name = '天天鸭' 定义然后 全局 通用即可。存放在内存刷新会清空。

注意:在 Vue 3 应用程序中,虽然可以直接将属性挂载到 window 对象上实现全局访问,但这并不是推荐的做法,因为直接修改全局对象可能会导致命名冲突、难以进行模块化管理以及不利于应用的封装与维护。 

用法:直接定义,可以是属性也可以是对象

window.duname = '天天鸭'
window.duObj = { test: '看看对象' }

引用:

console.log( window.duname);   // 天天鸭 
console.log( window.duObj);   // {test: '看看对象'}

十二、app.config.globalProperties

简单讲解:app.config.globalProperties 是Vue官方的一个 api,这是对 Vue 2 中 Vue.prototype 使用方式的一种替代,Vue.prototype 法在 Vue3 已经不存在了。与任何全局的东西一样,应该谨慎使用

 用法示例:在 main.js 文件挂载一个全局的 msg 属性

import { createApp } from 'vue'

const app = createApp(App)

app.config.globalProperties.msg = 'hello'

在其它页面使用 getCurrentInstance() 获取

import { getCurrentInstance } from "vue";

const { proxy } = getCurrentInstance() // 使用proxy,类似于vue2的this

console.log(proxy.msg);    // hello

总结:

参考与:https://juejin.cn/post/7356817667574284340

如果有那里不对或者有补充欢迎大佬指导。有幸能让你看到这里,希望给个点赞哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/966123.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EasyExcel 导出合并层级单元格

EasyExcel 导出合并层级单元格 一、案例 案例一 1.相同订单号单元格进行合并 合并结果 案例二 1.相同订单号的单元格进行合并2.相同订单号的总数和总金额进行合并 合并结果 案例三 1.相同订单号的单元格进行合并2.相同订单号的商品分类进行合并3.相同订单号的总数和总金额…

WPF 进度条(ProgressBar)示例一

本文讲述&#xff1a;WPF 进度条(ProgressBar)简单的样式修改和使用。 进度显示界面&#xff1a;使用UserControl把ProgressBar和进度值以及要显示的内容全部组装在UserControl界面中&#xff0c;方便其他界面直接进行使用。 <UserControl x:Class"DefProcessBarDemo…

LabVIEW自定义测量参数怎么设置?

以下通过一个温度采集案例&#xff0c;说明在 LabVIEW 中设置自定义测量参数的具体方法&#xff1a; 案例背景 ​ 假设使用 NI USB-6009 数据采集卡 和 热电偶传感器 监测温度&#xff0c;需自定义以下参数&#xff1a; 采样率&#xff1a;1 kHz 输入量程&#xff1a;0~10 V&a…

新能源产业的质量革命:六西格玛培训如何重塑制造竞争力

在新能源行业狂飙突进的今天&#xff0c;企业若想在全球供应链中占据高地&#xff0c;仅靠技术突破已远远不够。制造效率的毫厘之差&#xff0c;可能成为市场话语权的千里之距。某光伏巨头曾因电池片良率低于行业均值1.5%&#xff0c;导致年损失超2.3亿元——这恰恰印证了六西格…

(11)gdb 笔记(4):设置执行方向 set exec-direction,

&#xff08;28&#xff09;引入 record 后&#xff0c;可以 设置执行方向 set exec-direction &#xff1a; 实践&#xff1a; &#xff08;29&#xff09; &#xff08;33&#xff09; 谢谢

redis持久化理论

0 前言 什么是持久化 redis操作都是在内存中&#xff0c;如果出现宕机的话&#xff0c;数据将不复存在&#xff0c;所以持久化是将内存中的数据刷盘到磁盘中&#xff0c;redis可以提供RDB和AOF将数据写入磁盘中。 一 持久化技术 本章节将介绍持久化RDB和AOF两个技术&#xf…

25/2/7 <机器人基础>雅可比矩阵计算 雅可比伪逆

雅可比矩阵计算 雅可比矩阵的定义 假设我们有一个简单的两个关节的平面机器人臂&#xff0c;其末端执行器的位置可以表示为&#xff1a; 其中&#xff1a; L1​ 和 L2 是机器人臂的长度。θ1​ 和 θ2是关节的角度。 计算雅可比矩阵 雅可比矩阵 JJ 的定义是将关节速度与末…

鸿蒙UI(ArkUI-方舟UI框架)- 使用文本

返回主章节 → 鸿蒙UI&#xff08;ArkUI-方舟UI框架&#xff09; 文本使用 文本显示 (Text/Span) Text是文本组件&#xff0c;通常用于展示用户视图&#xff0c;如显示文章的文字内容。Span则用于呈现显示行内文本。 创建文本 string字符串 Text("我是一段文本"…

科技赋能数字内容体验的核心技术探索

内容概要 在数字化时代&#xff0c;科技的迅猛发展为我们的生活和工作带来了深刻的变革。数字内容体验已经成为人们获取信息和娱乐的重要途径&#xff0c;而这背后的技术支持则扮演着至关重要的角色。尤其是在人工智能、虚拟现实和区块链等新兴技术的推动下&#xff0c;数字内…

详细教程 | 如何使用DolphinScheduler调度Flink实时任务

Apache DolphinScheduler 非常适用于实时数据处理场景&#xff0c;尤其是与 Apache Flink 的集成。DolphinScheduler 提供了丰富的功能&#xff0c;包括任务依赖管理、动态调度、实时监控和日志管理&#xff0c;能够有效简化 Flink 实时任务的管理和部署。通过 DolphinSchedule…

棋盘(二维差分)

题目&#xff1a; 5396. 棋盘 题目 提交记录 讨论 题解 视频讲解 小蓝拥有 nnnn 大小的棋盘&#xff0c;一开始棋盘上全都是白子。 小蓝进行了 mm 次操作&#xff0c;每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋子变为黑色&#xff0c;黑色棋子变…

MySQL数据库基础(创建/删除 数据库/表)

一、数据库的操作 1.1 显示当前数据库 语法&#xff1a;show databases&#xff1b; <1>show 是一个关键字&#xff0c;表示要执行的操作类型 <2>databases 是复数&#xff0c;表示显示所有数据库 上面的数据库中&#xff0c;除了java113&#xff0c;其它的数据库…

【WebLogic】Oracle发布WebLogic 14c最新版本-14.1.2.0

根据Oracle官方产品经理的博客&#xff0c;Oracle于2024年12月20日正式对外发布了WebLogic 14c的第二个正式版本&#xff0c;版本号为 14.1.2.0.0 &#xff0c;目前官方已开放客户端下载。该版本除继续支持 Jakarta EE 8 版本外&#xff0c;还增加了对 Java SE 17&#xff08;J…

SQL Server 数据库迁移到 MySQL 的完整指南

文章目录 引言一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据 二、迁移工具的选择2.1 使用 MySQL Workbench2.2 使用第三方工具2.3 手动迁移 三、迁移步骤3.1 导出 SQL Server 数据库结构3.2 转换数据类型和语法3.3 导入 MySQL 数据库3.4 迁移数据3.5 迁移存…

springboot+vue导入ruoyi项目的框架

一、介绍 RuoYi-Vue版本&#xff0c;采用了前后端分离的单体架构设计软件环境&#xff1a;JDK、Mysql、Redis、Maven、Node技术选型: Spring Boot、Spring Security、MyBatis、Jwt、Vue3、Element-Plus官方地址: https://gitee.com/y_project/RuoYi-Vue 官方推荐的版本如下&a…

jvm 篇

字节码的作用 ‌跨平台性‌&#xff1a;字节码是Java实现跨平台特性的关键。Java源代码编译成字节码后&#xff0c;可以在任何安装了Java虚拟机&#xff08;JVM&#xff09;的设备上运行&#xff0c;这使得Java应用程序能够在不同的操作系统和硬件平台上运行而无需重新编译。‌…

【Springboot】Springboot 自定义线程池的参数配置最优是多少

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

【2】Cisco SD-WAN 组件介绍

1. 概述 Cisco SD-WAN 是一套基于软件定义的广域网(SD-WAN)解决方案,能够提供安全、可扩展且高效的网络连接。它通过集中的控制和智能路径选择,实现跨多个站点的可靠性、可见性和优化。 在 Cisco SD-WAN 体系架构中,主要由四个核心组件构成: vManage(管理平面) vSmart…

测试中的第一性原理:回归本质的质量思维革命

在软件工程领域&#xff0c;测试活动常被惯性思维和经验主义所主导——测试用例库无限膨胀、自动化脚本维护成本居高不下、测试策略与业务目标渐行渐远。要突破这种困境&#xff0c;第一性原理&#xff08;First Principles Thinking&#xff09;提供了独特的解题视角&#xff…

《chatwise:DeepSeek的界面部署》

ChatWise&#xff1a;DeepSeek的界面部署 摘要 本文详细描述了DeepSeek公司针对其核心业务系统进行的界面部署工作。从需求分析到技术实现&#xff0c;再到测试与优化&#xff0c;全面阐述了整个部署过程中的关键步骤和解决方案。通过本文&#xff0c;读者可以深入了解DeepSee…