Vue3组件通信和Vue2`的区别:

  • 移出事件总线,使用mitt代替
  • vuex换成了pinia

  • .sync优化到了v-model里面

  • $listeners所有的东西,合并到$attrs

  • $children被移除

自定义事件(与vue2语法差异)

自定义事件常用于子组件向父组件传递数据

原生事件:特点的click、hover等

自定义事件:事件名是任意名称,事件对象$event: 是调用emit时所提供的数据,可以是任意类型

  1. 在子组件声明自定义事件

    // 使用defineEmits在子组件声明一个test自定义事件
    // 参数是一个数组,可以包含多个自定义事件
    const emit = defineEmits(["test"])
  2. 在父组件绑定自定义事件

      <!-- 在父组件的子组件标签里面,绑定test事件,触发getInfo回调 -->
    <!-- 回调函数在父组件中 -->
    <UserInfo @test="getInfo"></UserInfo>
  3. 在子组件触发自定义事件

    // 在子组件中主动触发自定义事件
    // 触发事件的名称,要传递的数据
    emit("test",100)

mitt

与消息订阅与发布(pubsub)功能类似,可以实现任意组件间通信

  1. 安装mitt

    npm i mitt
  2. 创建mitt

    //  src/utils/emitter.ts
    
    // 引入
    import mitt from "mitt"; // 创建emitter,emitter可以绑定、触发事件
    const emitter = mitt() export default emitter
  3. 绑定事件

    // 要绑定的事件名,和处理的回调方法
    emitter.on("test1",(value)=>{
    console.log("on test1",value)
    })
  4. 触发事件

    // 要触发的组件名和传递的参数,在任意地方触发,所有绑定了对应事件的地方都会收到
    emitter.emit("test1", 6666)
  5. 查看全部事件

    emitter.all
  6. 解绑指定事件

    emitter.off("test1")
  7. 清理全部事件

    emitter.all.clear()
  8. 在接收数据的组件中,组件销毁之前解绑事件

    // 生命周期钩子
    onUnmounted(()=>{
    // 解绑事件
    emitter.off('test')
    })

v-model(与vue2实现区别)

实现父组件、子组件直接互相通信

  1. v-model的原理

    <!-- 实现双向绑定-->
    <input type="text" v-model="user"> <!-- v-model的本质是:先单向绑定user,然后有输入事件的时候,再将user赋值为输入的数据 -->
    <input
    type="text"
    :value="user"
    @input="user =(<HTMLInputElement>$event.target).value"
    >
  2. 组件标签上的v-model

    <!--  单纯v-model无法实现和子组件双向绑定 -->
    <UserInfo v-model="user"></UserInfo> <!-- 本质是: modelValue单向绑定数据到页面的显示,数据变化的时候 将user赋值为传递的数据 -->
    <UserInfo :modelValue="user" @update:model-value="user = $event" ></UserInfo> <!--
    user=$event的解释
    原生事件:$event是事件对象,target.value就是对应的值
    自定义事件,$event就是触发事件是所传递的值
    -->

    父组件和子组件双向通信:

    <UserInfo v-model="user"></UserInfo>

    在子组件中

    // 接收v-model的modelValue
    defineProps(["modelValue"]) // 声明事件
    const emit = defineEmits(['update:model-value'])
    <!-- value是props接收的modelValue,触发输入事件的时候,触发emit触发update,值是event.target.value-->
    <input type="text" :value="modelValue" @input="emit('update:model-value',(<HTMLInputElement>$event.target).value)">
  3. 修改modelValue

    <!-- :test 相当于不再使用modelValue传递数据,而是使用test  -->
    <UserInfo v-model:test="user"></UserInfo> <!-- 该方式一个表情上可以绑定多个不同的数据 -->
    <UserInfo v-model:test="user" v-model:test2="user2"></UserInfo>
    // 接收
    defineProps(["test","test2"]) // 声明
    const emit = defineEmits(['update:test','update:test2'])
    <input type="text" :value="test" @input="emit('update:test',(<HTMLInputElement>$event.target).value)">

$attrs

$attrs用于实现当前组件的父组件,向当前组件的子组件通信(祖→孙)

$attrs是一个对象,包含所有父组件传入的标签属性,会自动排除props中声明的属性(可以认为声明过的 props 被子组件自己消费了)

  1. 父组件

    <!-- 向子组件以props的形式传递 list 和user-->
    <UserInfo :list="list" :name="user"></UserInfo>
  2. 当前组件

    props只接收了name

    // 当前组件只接受了name
    defineProps(["name"])

    使用attrs将没有接收的数据,向子传递

      <Info v-bind="$attrs"></Info>
  3. 子组件

    // 祖先传递的props,父组件没有接收,通过attrs,在孙组件使用props接受
    // 如果在父组件props使用了,则子组件接收不到
    defineProps(['list'])
  4. 可以在祖先中实现一个方法,传递给子孙,子孙中触发,实现子孙向祖先传递数据

$refs

$refs用于 :父向子传递数据

  • 值为对象,包含所有被ref属性标识的DOM元素或组件实例
  1. ref属性

      <UserInfo ref="userObj "></UserInfo>
    // 通过该方法可以获取子组件实例对象,进行对应的操作,在子组件要进行defineExpose操作,将数据交给外部
    let userObj = ref()
  2. $refs

    // 回调函数,触发的地方参数传递$refs
    function getAll(v){
    // v是一个对象,包含所有有ref属性的子组件实例、DOM元素
    console.log(v)
    }
    <!-- 参数传递$refs -->
    <button @click="getAll($refs)"></button>

$parent

$parent用于:子向父传递数据

  • 值为对象,当前组件的父组件实例对象
  1. 父组件中,使用defineExpose将允许子操作的数据暴露出去

  2. 子组件

    // 回调函数,parent需要传递$parent
    function getAll(parent){
    // parent是一个对象,是当前组件的父组件的实例
    console.log(parent)
    }
    <!-- 参数传递$parent -->
    <button @click="getAll($parent)"></button>

provide和inject

实现祖孙组件直接通信,不需要通过中间组件

  1. 在祖先中通过provide配置向后代组件提供数据

    import {provide} from 'vue'
    // 给子孙提供的key、Value
    provide("user",user)
    // 也可以value传递一个对象,批量传递数据,也可以传递方法
  2. 在所有后代中都能通过inject配置声明接收的数据

    import {inject} from 'vue'
    // 接收祖先中传递的user
    let user = inject("user")

插槽(部分语法区别)

默认插槽
  1. 父组件中编写代码

    <!-- 在组件标签中嵌套代码-->
    <UserInfo>
    <p>hello world</p> </UserInfo>
  2. 子组件

    <template>
    <!-- 在子组件中,合适的地方使用slot,决定代码显示在哪里, 如果父没有嵌套代码,则会显示默认内容-->
    <slot> <p>default</p></slot> </template>
具名插槽

使用名字定义、使用插槽,可以插入多段不同名字的插槽代码

如果不定义名字,默认插槽的名字默认是default,在组件中使用多个默认擦嘴,因为都是default,会有数量问题

  1. 给插槽定义名字

      <UserInfo>
    <!-- v-slot 只能卸载组件标签和template -->
    <template v-slot:p-message>
    <p>hello world</p> </template> </UserInfo>
    <!-- 简写方式  使用#代替 v-slot-->
    <template #:p-message>
  2. 子组件使用

      <slot name="p-message"></slot>
作用域插槽

数据在组件的自身,数据生成的结构由组件的使用者来决定

  1. 子组件

    <!--  listData是子组件的数据 使用该方式,将listData传递到父组件 -->
    <slot :listData='listData'></slot>
  2. 父组件

    <!--  如果又有名字又有参数,v-slot:插槽名字=参数名 --> 
    
    <template v-slot="params">
    <!-- params是自定义接收的名称,是一个对象 --> <!-- 怎么使用数据、什么结构,由父组件决定-->
    <ul>
    <li v-for=" data of params.ListData" :key="data.id">{{data.name}}</li>
    </ul> </template>

vue3-组件通信的更多相关文章

  1. Vue中组件通信的几种方法(Vue3的7种和Vue2的12种组件通信)

    Vue3组件通信方式: props $emit expose / ref $attrs v-model provide / inject Vuex 使用方法: props 用 props 传数据给子组 ...

  2. 【Vue】计算属性 监听属性 组件通信 动态组件 插槽 vue-cli脚手架

    目录 昨日回顾 1 计算属性 插值语法+函数 使用计算属性 计算属性重写过滤案例 2 监听属性 3 组件介绍和定义 组件之间数据隔离 4 组件通信 父子通信之父传子 父子通信之子传父 ref属性 扩展 ...

  3. 关于React的父子组件通信等等

    //==================================================此处为父子组件通信 1.子组件调用父组件: 父组件将子组件需要调用方法存入props属性内,子组 ...

  4. Angular2 组件通信

    1. 组件通信 我们知道Angular2应用程序实际上是有很多父子组价组成的组件树,因此,了解组件之间如何通信,特别是父子组件之间,对编写Angular2应用程序具有十分重要的意义,通常来讲,组件之间 ...

  5. vue.js入门(3)——组件通信

    5.2 组件通信 尽管子组件可以用this.$parent访问它的父组件及其父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据.另外,在子组件中修改父组件的 ...

  6. Intent进行组件通信的一些体会

    Intent进行组件通信的原理 l  Intent协助应用间的交互与通讯 Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述.Android则根据此Intent的描述,负责找到对应 ...

  7. 进程外组件通信之免注册com通信【原创】

    最近在搞进程外组件通信的东西,写了个demo,免注册的,一直没调通,其实就是两个问题卡了好几天,也没找到有用的资料,试了好几天终于才解决,现简单记录下来,免得大家跟我走一样的弯路.下面com端程序名称 ...

  8. vue2.0 组件通信

    组件通信: 子组件要想拿到父组件数据 props 子组件不允许直接给父级的数据, 赋值操作如果想更改,父组件每次穿一个对象给子组件, 对象之间引用. 例子: <script> window ...

  9. React之组件通信

    组件通信无外乎,下面这三种父子组件,子父组件,平行组件(也叫兄弟组件)间的数据传输.下面我们来分别说一下: 父子组件: var Demo=React.createClass({ getInitialS ...

  10. Vue 非父子组件通信

    组件是Vue核心的一块内容,组件之间的通信也是很基本的开发需求.组件通信又包括父组件向子组件传数据,子组件向父组件传数据,非父子组件间的通信.前两种通信Vue的文档都说的很清楚,但是第三种文档上确只有 ...

随机推荐

  1. RxJS 系列 – Join Operators

    前言 前几篇介绍过了 Creation Operators Filtering Operators Join Creation Operators Error Handling Operators T ...

  2. 网络服务性能优化:Wrktcp与Perf工具详解

    wrktcp安装 码云地址:https://gitee.com/icesky1stm/wrktcp 直接下载,cd wrktcp-master && make,会生成wrktcp,就o ...

  3. [Tkey] OSU!

    更新的题解可看 此处 你说得对但是 恐怖日本病毒会自动向你的电脑中下载 OSU! 题意简述 一个 01 串,每个位置有 \(p_{i}\) 的概率为 \(1\),连续的 \(x\) 个 \(1\) 贡 ...

  4. AntDesign-Vue Table 查询与分页

    前言 之前的增删改查小 Demo 已经快要进行到最后一步了,这节的任务是将请求数据的方式改为 分页,并且增加 分页条件查询 的功能. 页面布局 <a-table :data-source=&qu ...

  5. 墨天轮高分技术文档分享——Oracle升级迁移篇(共96个)

    朋友们好久不见,在上期<墨天轮最受欢迎的技术文档-SQL优化篇>的留言中,有许多朋友表示想看数据库升级迁移相关的内容,经过搜集整理,这就为大家呈上!原文送墨值中,欢迎大家参与~ 数据库升级 ...

  6. python中字典的运算

    问题: 如何查找在两个字典中相同的键.值元素? dict1 = {'a': 1, 'b': 2, 'c': 3} dict2 = {'a': 10, 'y': 11,'b': 2} dict1.key ...

  7. 通过自定义字符串内插处理程序(InterpolatedStringHandler)和CallerArgumentExpression特性来实现一个好玩的场景

    背景知识介绍 什么是自定义字符串内插处理程序? 简单来讲就是自定义一个高性能的字符串拼接程序 通过 $"{a}{b}"的方式. 什么是CallerArgumentExpressio ...

  8. 云原生周刊 | 使用 kube-reqsizer 自动调整资源配额

    开源项目推荐 kptop Kubernetes API 提供的监控指标非常有限,而 kubectl top 就是利用 Kubernetes API 来查看 Node 和 Pod 的实时资源使用情况.k ...

  9. 一文彻底弄懂并解决Redis的缓存雪崩,缓存击穿,缓存穿透

    缓存雪崩.缓存击穿.缓存穿透是分布式系统中使用缓存时,常遇到的三类问题,都会对系统性能和稳定性产生严重影响.下面将详细介绍这三者的定义.产生原因.危害以及常见的解决方案. 1. 缓存雪崩 1.1 定义 ...

  10. Ubuntu 22.04 和 Windows 时间冲突解决方案

    默认情况下,Ubuntu(和大多数其他 Linux 发行版)假设硬件时钟设置为协调世界时间(UTC + 0),而 Windows 则假设硬件时钟设置为当地时间,这导致 Ubuntu 快 8 小时. 这 ...