vue3.0组件通信

这篇具有很好参考价值的文章主要介绍了vue3.0组件通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、props

没有加TS限制类型的时候

1. 数组写法
defineProps(['count', 'changCount'])
2. 对象写法
defineProps({
    count: Number,
    changCount: Function
})
3. 配置对象
defineProps({
    count: {
      type: Number,
      default: 2
    },
    changCount: {
      type: Function,
      required: true
    }
})

注意: defineProps()会返回一个对象,这个对象可以直接.出数据

const props = defineProps(['text'])

接到数据之后模板中直接写数据即可
js中需要使用 props.text 来获取数据

加TS写法

const props = defineProps<{
    count: number,
    // changCount: Function
    changCount: (n: number) => void // 定义到函数中具体的某个参数
}>()

规则:

  • 非函数类型
    基本数据类型 - 展示
    引用数据类型 - 展示,但是可以修改属性,不推荐(违反单向数据流 - 不是绝对禁止使用的,偷懒可以用)
  • 函数类型 - 子组件调用父组件传过来的函数,修改父组件的数据

2、自定义事件 - click事件,xxx自定义事件

自定义事件用于父子组件间的通信,子给父传参

两个角度分析

  • 元素绑定

    • 绑定原生事件 – 关注 事件类型(系统内置事件) 和 触发机制(浏览器触发)
    • 绑定自定义事件 – 无意义,没有触发机制
  • 组件绑定

    • 绑定原生事件

      v2中所有绑定在组件标签上的原生事件都会被理解成自定义事件,需要使用.native才能转成原生事件

      v3中所有绑定在组件标签上的原生事件会自动绑定到子组件的根标签上转变为原生事件, .native被移除了

      v3注意两个:

      • 没有根标签,原生事件将变成自定义事件

      • 有根标签,但是使用 defineEmits 接收过,也是自定义事件

    • 绑定自定义事件

      需要自己绑定,自己触发

总结:

在vue2中给组件绑定的事件都是自定义事件,通过.native可以把像click这种转成原生事件
在vue3中给组件绑定事件需要区分,像click这种事件,直接就是绑定的原生事件,绑定到组件的根标签身上
    这里移除了.native,
    1. 如果子组件没有根标签,此时这个click事件就变成了自定义事件,需要使用emit触发
    2. 如果子组件中使用 defineEmits 接收过绑定的事件,一定是自定义事件

写法:

不加TS类型
    const emit = defineEmits(['click', 'xxx'])TS类型
    const emit = defineEmits<{
        (e: 'xxx'): void
        (e: 'customeEvent', arg: number): void
    }>()
	// 使用
	emit('xxx')
	emit('customeEvent', 22)

	注意: 在 defineEmits 中定义函数的时候 `(e: 'xxx'): void` 里面的e是一个参数,类型是一个具体的值,原理和 const a: '我爱你' = '我爱你' 一样,相当于给 e 设置了一个值类型,值类型也是一个类型

注意:在vue2中和vue3中的$event都是一样的

3、pubsub

1. 安装
    npm i pubsub-js
2. 接收参数的组件,订阅消息(绑定事件),留下回调,接收参数
    Pubsub.subscribe('changeMessage', changeMessage)
3. 发送参数的组件,发布消息(触发事件),传递参数
    Pubsub.publish('changeMessage', 'string')

注意:

pubsub的接收参数回调中,参数一是消息类型,参数二才是我们正儿八经传递的参数

declare 在 .d.ts 文件进行全局类型声明
注意: 使用第三方包有时候可能回飘红,因为第三方包没有兼容TS类型,需要自己手动声明
env.d.ts文件声明类型、模块、接口的(告诉TS)

declare module 'pubsub-js' // 告诉TS pubsub是一个模块,直接用即可,TS就不会飘红了

// declare相当于声明了一个类型
// 这里的abc可以理解成等号右侧的类型别名
declare type abc = '我爱你' | undefined

// declare声明一个接口
declare interface qwer {
  name: string
}

因为这些声明在 .d.ts 文件中,所以全局可以使用

4、v-model

思路: 从vue2一步步推出vue3的v-model

  • vue2中v-model的推倒
<CustomInput :value="text" @input="text = $event"></CustomInput>//生效

<CustomInput v-model="text"></CustomInput>//当前行vue2的v-model不生效,所以说vue3中这种写法不行了

CustomInput
v-model 用于收集表单数据,用于组件是父子组件之间的数据同步
在vue2当中v-model是通过两个条件 1. :value 2. @input实现的
在vue3使用v-model="text"简写形式不能实现
结论:vue3中不是这两个条件实现的

  • vue2中.sync的推倒
<CustomInput2 :text="text" @update:text="text = $event"></CustomInput2>//生效
<CustomInput2 :text.sync="text"></CustomInput2>//使用.sync的简写在vue3中也不生效

在vue2中还有一个父子间的数据同步, .sync
.sync 的实现也是两个条件 :xxx 和 @update:xxx
试试.sync的实现 在vue3中也不生效

  • 结论 vue3中v-model的使用

CustomInput2
那么vue3是如何实现的?
vue3 v-model 是通过 :modelValue 和 @update:modelValue 实现的
vue3把.sync移除了,相当于把v-model和.sync统一成一个了
<CustomInput2 :modelValue="message" @update:modelValue="message = $event"></CustomInput2>
<CustomInput2 v-model:modelValue="message"></CustomInput2>
<CustomInput2 v-model="message"></CustomInput2>
注意: 这里只有 绑定的是modelValue可以简写

CustomInput3
为什么把v-model和.sync统一了?
在vue2中v-model组件只能绑定一个,.sync可以绑定多个
vue2中v-model的实现必须是 :value 和 @input,绑定value只能绑定一个value
vue2中.sync的实现:xxx 和 @update:xxx 没有限制几个数据,想绑定几个就绑定几个
在vue3当中,一个组件可以使用多个v-model了,封装一个 CustomInput3 中写多个input框
<CustomInput3 v-model="message" v-model:text="text"></CustomInput3>
v-model:text 需要实现 :text 和 @update:text

5、attrs

vue2中 $attrs,获取到除去props接收过的属性,class、style,其他属性都可以接收到

vue2中 $listener,可以获取到所有的自定义事件

vue3中,$listener移除了

vue3中的attrs使用

1. 引入 useAttrs
    import { useAttrs } from 'vue'
2. 调用 useAttrs 方法得到一个对象
    const attrs = useAttrs();
这个对象可以接收到除了 props已经接收过的数据 和 emit接收过的事件 ,其他的都可以接收到(包括绑定的属性和事件)
(注意:这里class和style的样式会被应用于子组件)


需求: 封装HintButton组件,一个带有提示的button组件(使用 element)
    el-button 组件中的配置项多了,一个一个暴露吗?
    不是,使用 attrs 得到传进来的属性和方法,绑定到el-button组件上,作用于el-button这个组件
    通过 v-bind="attrs" 把接收到的属性和事件都绑定到el-button组件上

6、$ref-$parent

总结

  1. $ref - 拿组件实例-拿元素
    父组件拿子组件数据:

    <Son ref="sonRef" />
     
    const sonRef = ref()
    const borrowMoneyfromXM = () => {
      sonRef.value.money -= 100
    }
    

    声明的变量必须和组件上的ref属性值相同才能拿到组件实例

    组件实例中的内容是看不到的,需要使用 defineExpose({ money }) 暴露才可以被外部观看到
    子组件暴露数据:

    defineExpose({
       money
     })
    
  2. $parent 没有移除 $children被移除了

    $parent通过模板传参可以获取到 父组件
    子组件:

    <button @click="giveMoney($parent)">BABA: 50</button>
    
    const giveMoney = (parent: any) => { // 当实在不知道什么类型的时候用any
      parent.money += 50
    }
    
    

    父组件暴露数据:

    defineExpose({
       money
    })
    

7、provide-inject

用于祖孙之间的通信
vue2中
provide广播,只有初始化的时候广播一次,之后数据发生改变的时候后面接收不到
除了对象的属性,对象的地址改变后代接收不到,对象的属性改变后代能接收到

vue3
vue3中的数据ref对象、reactive对象都是对象,对象的属性变化(ref对象的.value属性)后代能拿到
provide广播对象的对象是proxy对象,不处理,不是proxy对象,用reactive处理一下变成proxy对象

import { provide } from 'vue';
provide('content11', content11)

import { inject } from 'vue'
const content11 = inject('content11')

总结: vue3中数据的变化后代是可以拿到的(因为广播出去的都是对象)

祖先抛过来的数据
     后代接收到之后可以改变(因为是ref对象,改的是ref对象的.value属性)
     祖先改变数据之后,后代也可以接收到(因为是ref对象,改变的是ref对象的.value属性)
使用ref对象无法验证出,provide初始化的时候只给后代抛了一次数据
     使用了个基本数据类型,虽然没有响应式,我们也可以让数据发生变化,后代确实没有接收到
结论:
   provide 和 inject 初始化的时候只给后代抛一次数据
   如果是ref对象的话,后代可以接收到数据的.value属性变化(因为传给后代的是ref对象的地址)

8、slot -插槽 和vue2一样

9、mitt

mitt 用来进行跨组件的通信的

使用步骤:

  1. 下载安装
    npm i mitt
  2. 创建实例,用实例进行跨组件间的通信(src/utils/mitt.ts文件)
    import mitt from "mitt";
    export default mitt();
  3. 接收数据的组件,找到mitt,绑定事件,留下回调,接收参数
    mitt.on('xxx', receiveData)
  4. 发送数据的组件,找到mitt,触发事件,传递参数
    mitt.emit('xxx', '我爱你')
  5. 解绑固定事件
    emitter.off('foo', onFoo) // unlisten
  6. 解绑所有事件
    emitter.all.clear()
    注意:使用mitt的时候需要加类型,类型中放的是事件的名称
import mitt from "mitt";

type EventType = {
  xxx: string
}

export default mitt<EventType>(); // 这个实例用来进行跨组件的通信

npm mitt 链接 https://www.npmjs.com/package/mitt文章来源地址https://www.toymoban.com/news/detail-650396.html

到了这里,关于vue3.0组件通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3 组件之间的通信

    经过前面几章的阅读,相信开发者已经可以搭建一个基础的 Vue 3 项目了! 但实际业务开发过程中,还会遇到一些组件之间的通信问题,父子组件通信、兄弟组件通信、爷孙组件通信,还有一些全局通信的场景。 这一章就按使用场景来划分对应的章节吧,在什么场景下遇到问

    2023年04月08日
    浏览(44)
  • vue3-父子组件间通信

    在实际业务开发的过程中,我们时常会遇到组件间的通信问题,比如:父子组件间通信、同级组件间通信等。本篇文章中主要介绍父子组件间通信。父子组件间通信主要有以下常见形式: 方案 父组件向子组件 子组件向父组件 props/emits props emits v-model/emits v-model emits ref/emits

    2024年02月05日
    浏览(61)
  • vue3 快速入门系列 —— 组件通信

    组件通信在开发中非常重要,通信就是你给我一点东西,我给你一点东西。 本篇将分析 vue3 中组件间的通信方式。 Tip :下文提到的绝大多数通信方式在 vue2 中都有,但是在写法上有一些差异。 在 vue3 基础上进行。 新建三个组件:爷爷、父亲、孩子A、孩子B,在主页 Home.vu

    2024年04月17日
    浏览(64)
  • 【vue3】学习笔记--组件通信方式

    学习vue3总是绕不开vue2 vue3组件通信方式如下: props数据只读,从父组件传递到子组件,子组件内部不可直接更改 子组件需要使用defineProps方法接受父组件传递过来的数据 setup语法糖下局部组件无需注册直接可以使用 父组件 子组件 vue框架中事件分为两种:原生的DOM事件和自定

    2024年02月13日
    浏览(49)
  • vue3组件通信之pinia

      在vue3,vue的状态管理也迎来了新的变更,在vue3使用新的组件pinia来代理原有的vuex。pinia相比vuex,功能收敛了不少,比如不直接暴露setter方式,外部直接修改数据 vuex:集中式管理状态容器,可以实现任意组件之间通信 核心概念:state、mutations、actions、getters、modules pinia:集中式

    2024年02月11日
    浏览(40)
  • Vue3组件通信相关内容整理

    适用于:  父向子传递参数、方法, 子触发父传递的方法 props方式组件通信和vue2中的props传参类似,只是使用方式和接收方式有一些区别。 注意点: 通过props方式传递的参数为 只读属性,不可修改 父组件 子组件  组件A :绑定事件-接收数据  组件B:触发事件-传递数据 这

    2024年01月25日
    浏览(44)
  • Vue3组件间的通信方式

    目录  1.props父向子组件通信 2.自定义事件 子向父组件通信 3.全局事件总线 4.v-model组件通信(父子组件数据同步) 绑定单个数据同步  绑定多个数据同步  5.useAttrs组件通信  6.ref与$parent ref获取子组件实例对象  $parent获取父组件实例对象  7.provide-inject 可以实现隔辈传输 8.

    2024年02月17日
    浏览(44)
  • vue3探索——组件通信之依赖注入

    通常情况下,当我们需要从父组件向子组件传递数据时,会使用  props 。想象一下这样的结构:有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递

    2024年02月10日
    浏览(41)
  • vue3探索——组件通信之事件总线

    Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用 mitt.js 。 比起Vue实例上的 EventBus , mitt.js 好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件的监听和批量移除,它还不依赖Vue实例,所以可以跨框架使用,React或者Vue,甚至jQuery项目都能使用同一套库。 使用yarn安装

    2024年02月12日
    浏览(45)
  • VUE3+TS(父子、兄弟组件通信)

    目录 父传子值、方法(子调用父值、方法) 子传父值(父调用子值) 父读子(子传父)(父调用子值、方法) 兄弟(任意组件)通信 引入Mitt来完成任意组件通信 1、统一规范写法,通过在子组件标签上绑定属性和值,来传递到子组件,子组件再通过defineProps来接收,先给其

    2023年04月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包