vue3中的组件通信

前言:

vue3有两种setup写法,本文将用最简洁的代码例子针对主流的<script setup>写法对每一种用法进行说明

  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 (全局)

一、props

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

案例演示.

父组件代码: 通过自定义动态属性 :name=“name” 把name字段传给子组件。

<template>
  <child :text='str' :list="list"></child>
</template>

<script setup>
import { ref } from 'vue'
import child from './child.vue'
const str=ref('hello')
const list = ref(['a','b'])

</script>


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

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

<script setup>
import { defineProps } from 'vue'
const props = defineProps({
  text:{
  type:String,
  default:'abc'
  },
  list: {
    type: Array,
    default: [],
  },
})

//简写
const props = defineProps(['lsit','text']</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>
  <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>

子组件代码: $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宏,直接不需要propsemit就实现了父子通信效果,非常简洁好用。

七、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传参

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

十、pinia

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

十一、浏览器缓存

localStorage 和sessionStorage: 这算是用的不多,但也是必用的一种通信方式了,下面看看区别:
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 2Vue.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

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

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

相关文章

2024年大热,Access平替升级方案,也适合Excel用户

欢迎各位看官&#xff0c;您来了&#xff0c;就对了&#xff01; 您多半是Access忠实粉丝&#xff0c;至少是excel用户&#xff0c;亦或是WPS用户吧。那就对了&#xff0c;今天的分享肯定对您有用。 本文1100字&#xff0c;阅读时长2分50秒&#xff01; 现实总是不尽人意&am…

解决idea使用maven打包时无法将本地lib库文件和resource目录中的资源文件打包进jar文件的问题!!!

一、问题复现 1&#xff09;项目结构如下 我们看到项目中手动添加了本地lib资源&#xff0c;同时bootspring的配置文件和mapper文件也放在了resouces目录中。 2&#xff09;上述结构的项目在使用maven打包时&#xff0c;最终生成的jar文件中将不包含lib库文件&#xff0c;甚…

PKO-LSSVM-Adaboost班翠鸟优化最小二乘支持向量机结合AdaBoost分类模型

PKO-LSSVM-Adaboost班翠鸟优化最小二乘支持向量机结合AdaBoost分类模型 目录 PKO-LSSVM-Adaboost班翠鸟优化最小二乘支持向量机结合AdaBoost分类模型效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.PKO-LSSVM-Adaboost班翠鸟优化最小二乘支持向量机结合AdaBoost分类模…

FPGA实战篇(呼吸灯实验)

1.呼吸灯简介 呼吸灯采用 PWM 的方式&#xff0c;在固定的频率下&#xff0c;通过调整占空比的方式来控制 LED 灯亮度的变化。 PWM&#xff08;Pulse Width Modulation &#xff09;&#xff0c;即脉冲宽度调制&#xff0c;它利用微处理器输出的 PWM 信号&#xff0c;实现对…

家政小程序开发,打造便捷家政生活小程序

目前&#xff0c;随着社会人就老龄化和生活压力的加重&#xff0c;家政服务市场的需求正在不断上升&#xff0c;家政市场的规模也正在逐渐扩大&#xff0c;发展前景可观。 在市场快速发展的影响下&#xff0c;越来越多的企业开始进入到市场中&#xff0c;同时家政市场布局也发…

《Python基础》之Pandas库

目录 一、简介 二、Pandas的核心数据结构 1、Series 2、DataFrame 三、数据读取与写入 1、数据读取 2、数据写入 四、数据清洗与处理 1、处理缺失值 2、处理重复值 3、数据转换 五、数据分析与可视化 1、统计描述 2、分组聚合 3、数据可视化 六、高级技巧 1、时…

Elasticsearch在liunx 中单机部署

下载配置 1、下载 官网下载地址 2、上传解压 tar -zxvf elasticsearch-XXX.tar.gz 3、新建组和用户 &#xff08;elasticsearch 默认不允许root账户&#xff09; #创建组 es groupadd es #新建用户 useradd ryzhang -g es 4、更改文件夹的用户权限 chown -R ryzhang …

基于 MVC 的 SpringBoot 高校行政事务管理系统:设计思路与实现步骤详解

2系统开发环境 2.1vue技术 Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 [5] 与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第…

不敢相信,Nginx 还能这么玩?

大家好&#xff0c;我是程序员鱼皮。今天来聊聊 Nginx 技术&#xff0c;这是一个企业项目必用&#xff0c;但是却经常被程序员忽略的技术。学好 Nginx&#xff0c;可以助你在求职中脱颖而出。 或许你会想&#xff1a;“Nginx 不就是用来部署网站的服务器嘛&#xff1f;这有何难…

【AI系统】指令和存储优化

指令和存储优化 除了应用极广的循环优化&#xff0c;在 AI 编译器底层还存在指令和存储这两种不同优化。 指令优化 指令优化依赖于硬件提供的特殊加速计算指令。这些指令&#xff0c;如向量化和张量化&#xff0c;能够显著提高计算密度和执行效率。向量化允许我们并行处理数…

底部导航栏新增功能按键

场景需求&#xff1a; 在底部导航栏添加power案件&#xff0c;单击息屏&#xff0c;长按 关机 如下实现图 借此需求&#xff0c;需要掌握技能&#xff1a; 底部导航栏如何实现新增、修改、删除底部导航栏流程对底部导航栏部分样式如何修改。 比如放不下、顺序排列、坑点如…

基于Matlab卡尔曼滤波的GPS/INS集成导航系统研究与实现

随着智能交通和无人驾驶技术的迅猛发展&#xff0c;精确可靠的导航系统已成为提升车辆定位精度与安全性的重要技术。全球定位系统&#xff08;GPS&#xff09;和惯性导航系统&#xff08;INS&#xff09;在导航应用中各具优势&#xff1a;GPS提供全球定位信息&#xff0c;而INS…

Jenkins升级到最新版本后无法启动

1. 场景还原 最近在web界面将jenkins升级到最新版本后&#xff0c;后台无法启动jenkins服务&#xff0c;服务状态如下&#xff1a; 运行jenkins命令提示invalid Java version jenkins --version jenkins: invalid Java version: java version "1.8.0_202" Java(TM)…

shell编程 1 (泷羽sec)

声明 学习视频来自B站UP主 泷羽sec,如涉及侵泷羽sec权马上删除文章。 笔记只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 这节课旨在扩大自己在网络安全方面的知识面&#xff0c;了解网络安全领域的见闻&#xff0c;了…

威联通-001 手机相册备份

文章目录 前言1.Qfile Pro2.Qsync Pro总结 前言 威联通有两种数据备份手段&#xff1a;1.Qfile Pro和2.Qsync Pro&#xff0c;实践使用中存在一些区别&#xff0c;针对不同备份环境选择是不同。 1.Qfile Pro 用来备份制定目录内容的。 2.Qsync Pro 主要用来查看和操作文…

【机器学习】分类任务: 二分类与多分类

二分类与多分类&#xff1a;概念与区别 二分类和多分类是分类任务的两种类型&#xff0c;区分的核心在于目标变量&#xff08;label&#xff09;的类别数&#xff1a; 二分类&#xff1a;目标变量 y 只有两个类别&#xff0c;通常记为 y∈{0,1} 或 y∈{−1,1}。 示例&#xff…

GaussDB(类似PostgreSQL)常用命令和注意事项

文章目录 前言GaussDB&#xff08;类似PostgreSQL&#xff09;常用命令和注意事项1. 连接到GaussDB数据库2. 查看当前数据库中的所有Schema3. 进入指定的Schema4. 查看Schema下的表、序列、视图5. 查看Schema下所有的表6. 查看表结构7. 开始事务8. 查询表字段注释9. 注意事项&a…

点灯大师——WIFI控制灯

在之前的教程中&#xff0c;我们学习了 ESP6266 的原理&#xff0c;并动手写了驱动&#xff0c;实现了串口的通讯和 STA、AP、STAAP 三种模式。本次我们就来教大家如何使用 ESP8266 控制灯。这是一个简单的示例&#xff0c;展示了如何将 WIFI 通信与硬件控制相结合&#xff0c;…

如何使用brew安装phpredis扩展?

如何使用brew安装phpredis扩展&#xff1f; phpredis扩展是一个用于PHP语言的Redis客户端扩展&#xff0c;它提供了一组PHP函数&#xff0c;用于与Redis服务器进行交互。 1、cd到php某一版本的bin下 /usr/local/opt/php8.1/bin 2、下载 phpredis git clone https://githu…

Android 使用OpenGLES + MediaPlayer 获取视频截图

概述 Android 获取视频缩略图的方法通常有: ContentResolver: 使用系统数据库MediaMetadataRetriever: 这个是android提供的类&#xff0c;用来获取本地和网络media相关文件的信息ThumbnailUtils: 是在android2.2&#xff08;api8&#xff09;之后新增的一个&#xff0c;该类为…