VUE3(四)、组件通信

1、props

        作用:子组件之间的通信。
父传子:属性值的非函数。
子传父:属性值是函数。

       父组件:

<template><div>{{ childeData }}</div>——————————————————————————————<child :parentData="parentData" :sendData="getChildData"/>
</template>
<script setup lang="ts" name="parentIndex">
import { ref } from 'vue';
import child from './childeIndex.vue'const childeData=ref("");
const parentData=ref("parentData");function getChildData(data:string){childeData.value=data;
}</script>

        子组件:

<template><div>{{ parentData }}</div><button @click="sendData(data)"></button>
</template>
<script setup lang="ts" name="child">
import { ref } from 'vue'
defineProps(['parentData','sendData'])const data=ref('aaa')</script>

2、自定义事件

        通过父组件定义函数,子组件调用父组件的函数来实现参数的传递。

        父组件:

<template><div>{{ childeData }}</div>——————————————————————————————<child @send-toy="getChildData"/>
</template>
<script setup lang="ts" name="parentIndex">
import { ref } from 'vue';
import child from './childeIndex.vue'const childeData=ref("");function getChildData(data:string){childeData.value=data;
}</script>

        子组件:

<template><div>子组件</div><button @click="sendDat"></button>
</template>
<script setup lang="ts" name="child">import { ref } from 'vue'let data=ref('我是子组件')const emit = defineEmits(['send-toy'])function sendDat(){emit('send-toy',data)}</script>

3、mitt

        实现任意组件的通信。个人理解:在组件与组件之间提供了一个平台,都向这个平台发送、读取数据。
安装步骤:

  1. npm i mitt
  2. 新建文件utiles/emitter.ts
  3. 在需要的文件中引入emitter,进行绑定 事件,或调用事件。
  4.  在文件中进行解绑(unmounted中)

       emitter.ts

import mitt from 'mitt'
const emitter=mitt()
export default emitter

        获取数据的文件

<template><h2>child2中的数据:{{ src }}</h2>
</template>
<script setup lang="ts" name="child1">import { onUnmounted, ref } from 'vue'import emitter from '@/utils/emitter'const src=ref('')//监听事件emitter.on('getData',(data:string)=>{src.value=data})//在组件销毁时取消监听onUnmounted(()=>{emitter.off('getData')})
</script>

        发送数据的文件

<template><h2>child2的数据:{{ data }}</h2><button @click="getdata"> 点击获取数据 </button>
</template>
<script setup lang="ts" name="child2">import { ref } from 'vue'import emitter from '@/utils/emitter'const data = ref('222')function getdata(){emitter.emit('getData',data)}
</script>

4、v-model

        原理:实现双向绑定,通过传递props参数实现父传子,通过emit传递input或者点击事件实现子传父。

        父组件:

<template><!-- 这个写法的本质就是下面那种 --><input type="text" v-model="str"/><input type="text" :value="str" @input="str=(<HTMLInputElement>$event.target).value"/><!-- 自定义组件,一二种方法一致 --><selfInput v-model="str"></selfInput><!-- 此处的$event就是传递的数据 --><selfInput :modelValue="str" @update:modelValue="str=$event"></selfInput></template>
<script setup lang="ts" name="parentIndex">
import { ref } from 'vue';
import selfInput from './selfInput.vue';let str = ref('');
</script>

        自定义组件(selfInput.vue):

<template><input type="text" :value="modelValue" @input="emit('update:modelValue',($event.target as HTMLInputElement).value)"/>
</template>
<script setup lang="ts" >
import { ref,defineProps,defineEmits } from 'vue';defineProps(['modelValue'])const emit = defineEmits(['update:modelValue'])</script>

如果自定义自定义组件中的名称,可以实现多个组件的双向绑定。

        父组件:

<template>{{ str }} --------{{ pass }}<selfInput v-model:name="str" v-model:pass="pass"></selfInput> 
</template>
<script setup lang="ts" name="parentIndex">
import { ref } from 'vue';
import selfInput from './selfInput.vue';let str = ref('');
let pass = ref('');
</script>

        子组件:

<template><input type="text" :value="name" @input="emit('update:name',($event.target as HTMLInputElement).value)"/><input type="text" :value="pass" @input="emit('update:pass',($event.target as HTMLInputElement).value)"/>
</template>
<script setup lang="ts" >
import { ref,defineProps,defineEmits } from 'vue';defineProps(['name','pass'])const emit = defineEmits(['update:name','update:pass'])</script>

5、$attrs

        作用:适用于当前组件,向子组件通信(祖-->孙)。
当父组件给子组件传递参数,且子组件没有使用props进行接收时,所传递的参数存在attrs中。在子组件中使用$attrs就可以获取所有未被接收的数据。

        父组件:

<template><div>{{ a }}</div><hr/><div>{{ b }}</div><hr/><div>{{ c }}</div><hr/><child v-bind="{a,b,c}" @changeA="changeA"></child>
</template>
<script setup lang="ts" name="parentIndex">
import { ref } from 'vue';
import child from './chile.vue';
let a=ref(1);
let b=ref(2);
let c=ref(3);
function changeA(value:number){a.value=value;
}
</script>

        子组件:

<template><div>{{ a }}</div><hr/>--------------------------------<sun v-bind="$attrs"></sun>
</template>
<script setup lang="ts" name="chile">import sun from './sun.vue'defineProps(['a'])
</script>

        孙组件:

<template><div>{{ b }}</div><hr/><div>{{ c }}</div><hr/><button @click="changeAa">修改a</button>
</template>
<script setup lang="ts" >const num=defineProps(['b','c']);const emit=defineEmits(['changeA']);function changeAa(){emit('changeA',num.b);}
</script>

6、$refs、$parent

        $refs:用于父组件修改子组件中的数据。获取所有子组件暴露的数据。
$parent:用于子组件修改父组件的数据。获取父组件所有暴露的数据。

        以上的前提:使用defineExpose暴露数据。

        父组件:

<template><h1>父组件数据</h1><h1>{{ a }}</h1><button @click="changeChildeA($refs)">修改子组件数据</button><br/>--------------------------------<child1 ref="child1"/>--------------------------------<child2 ref="child2"/>
</template>
<script setup lang="ts" name="parentIndex">
import { ref } from 'vue';
import child1 from './childe1.vue';
import child2 from './childe2.vue';
let a=ref(1);
function changeChildeA(refs:any){refs.child1.b++;refs.child2.b++;
}
defineExpose({a})
</script>

        子组件1:

<template>    <h1>子组件数据</h1><h1>a:{{ a }}</h1><h1>b:{{ b }}</h1><button @click="changeParent($parent)">修改父组件的a</button>
</template>
<script setup lang="ts" >
import { ref } from 'vue'
let a=ref(1)
let b=ref(1)
function changeParent(parent:any){parent.a++
}
//暴露
defineExpose({b
})
</script>

        子组件2:

<template>    <h1>子组件数据</h1><h1>a:{{ a }}</h1><h1>b:{{ b }}</h1>
</template>
<script setup lang="ts" >
import { ref } from 'vue'
let a=ref(1)
let b=ref(1)//暴露
defineExpose({a,b
})
</script>

7、provide、inject

        作用:实现祖孙组件之间的数据传递。
传递数据:provide(“数据名称”,数据)。
接收数据:inject(“数据名称”,默认值)。

        父组件:

<template><h1>父组件数据</h1><h1>{{ a }}</h1>--------------------------------<child1 ref="child1"/>
</template>
<script setup lang="ts" name="parentIndex">
import { ref,provide } from 'vue';
import child1 from './childe1.vue';let a=ref(0);
function changeA(value:number){a.value+=value;
}provide("parent",{a:a,changeA})</script>

        子组件:

<template>    <h1>子组件数据</h1><h1>a:{{ a }}</h1><div><button @click="changeA(1)">更改父组件的a</button></div>
</template>
<script setup lang="ts" >
import { ref,inject } from 'vue'
let {a,changeA} = inject('parent',{a:ref(0),changeA:function(x:number){}})
</script>

8、插槽

        作用:引入组件时可以给组件传递一些HTML元素。        

默认插槽

        父组件中引入子组件时,子组件标签内部的元素就是会传入slot的参数。
子组件中的slot就相当于占位符,给未来传进来的元素预留空位。

        父组件:

<template><h1>父组件数据</h1><div class="child"><child1 :title="'第一个'"><div style="color: aqua;">1111111111</div></child1><child1 :title="'第二个'"><div style="color:black;">22</div></child1></div>
</template>
<script setup lang="ts" name="parentIndex">
import child1 from './childe.vue';
</script>
<style scoped>

        子组件:

    <div class="child"><h1 style="color: black;">{{ title }}</h1><slot>默认值</slot></div></template>
<script setup lang="ts" >defineProps(['title'])
</script>

具名插槽

        作用:可以指定元素插入的位置。
用法:在定义插槽位置时,使用name属性定义其名字。
在应用组件时,在其标签或Templet标签内部定义v-slot(或使用#+名字)属性。

        父组件:      

<template><h1>父组件数据</h1><div class="child"><child1 :title="'第一个'"><template #b><div style="color: aqua;">1111111111</div></template></child1><child1 :title="'第二个'"><template #a><div style="color:black;">22</div></template></child1></div>
</template>
<script setup lang="ts" name="parentIndex">
import child1 from './childe.vue';
</script>

        子组件:

<template>    <div class="child"><h1 style="color: black;">{{ title }}</h1><slot name="a">默认值</slot><h1>-------------分隔符--------------------</h1><slot name="b">默认值</slot></div></template>
<script setup lang="ts" >defineProps(['title'])
</script>

作用域插槽

        作用:当父组件需要子组件的数据。
用法:在定义slot标签时,使用props写法进行传递参数。
在父组件中使用v-slot拿到参数。
如果同时使用了具名插槽:v-slot:name=‘parms’               

        父组件:

<template><h1>父组件数据</h1><div class="child"><child1 :title="'第一个'"><template #a="{game,a}"><ul><li v-for="item in game" :key="item.id">{{ item.name }}</li></ul></template></child1></div>
</template>
<script setup lang="ts" name="parentIndex">
import child1 from './childe.vue';
</script>

       子组件:

<template>    <div class="child"><h1 style="color: black;">{{ title }}</h1><slot name="a" :game="game" :a="a">默认值</slot></div></template>
<script setup lang="ts" >
import { reactive } from 'vue'; defineProps(['title'])const game=reactive([{id:1,name:'a'},{id:2,name:'b'},])const a=1;
</script>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构与算法】数据结构初阶:详解二叉树(六)——二叉树应用:二叉树选择题

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人生格言&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为…

Android广播实验

【实验目的】了解使用Intent进行组件通信的原理&#xff1b;了解Intent过滤器的原理和匹配机制&#xff1b;掌握发送和接收广播的方法【实验内容】任务1、普通广播&#xff1b;任务2、系统广播&#xff1b;任务3、有序广播&#xff1b;【实验要求】1、练习使用静态方法和动态方…

html转word下载

一、插件使用//转html为wordnpm i html-docx-js //保存文件到本地npm i file-saver 注&#xff1a;vite 项目使用esm模式会报错&#xff0c;with方法错误&#xff0c;修改如下&#xff1a;//直接安装修复版本npm i html-docx-fixed二、封装导出 exportWord.jsimport htmlDocx f…

北方公司面试记录

避免被开盒&#xff0c;先称之为“北方公司”&#xff0c;有确定结果后再更名。 先说流程&#xff0c;线下面试&#xff0c;时间非常急&#xff0c;下午两点钟面试&#xff0c;中午十二点打电话让我去&#xff0c;带两份纸质简历。 和一般的菌工单位一样&#xff0c;先在传达室…

linux——ps命令

PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND0 1 1 1 ? -1 Ss 0 0:01 /usr/lib/systemd/systemd1 123 123 123 ? -1 S 0 0:00 /usr/sbin/sshd -D123 456 456 456 pts/0 456 R 10…

C#.NET 依赖注入详解

一、是什么 在 C#.NET 中&#xff0c;依赖注入&#xff08;Dependency Injection&#xff0c;简称 DI&#xff09; 是一种设计模式&#xff0c;用于实现控制反转&#xff08;Inversion of Control&#xff0c;IoC&#xff09;&#xff0c;以降低代码耦合、提高可测试性和可维护…

Vue监视数据的原理和set()的使用

在 Vue 中&#xff0c;Vue.set()&#xff08;或 this.$set()&#xff09;是用于解决响应式数据更新检测的重要方法&#xff0c;其底层与 Vue 的数据监视原理紧密相关。以下从使用场景和实现原理两方面详细说明&#xff1a;一、Vue.set () 的使用场景与用法1. 为什么需要 Vue.se…

在 Vue 中,如何在回调函数中正确使用 this?

在 Vue 组件中&#xff0c;this 指向当前组件实例&#xff0c;但在回调函数&#xff08;如定时器、异步请求、事件监听等&#xff09;中&#xff0c;this 的指向可能会丢失或改变&#xff0c;导致无法正确访问组件的属性和方法。以下是在回调函数中正确使用 this 的几种常见方式…

第4章唯一ID生成器——4.4 基于数据库的自增主键的趋势递增的唯一ID

基于数据库的自增主键也可以生成趋势递增的唯一 ID&#xff0c;且由于唯一ID不与时间戳关联&#xff0c;所以不会受到时钟回拨问题的影响。 4.4.1 分库分表架构 数据库一般都支持设置自增主键的初始值和自增步长&#xff0c;以MySQL为例&#xff0c;自增主键的自增步长由auto_i…

设计模式:Memento 模式详解

Memento 模式详解Memento&#xff08;备忘录&#xff09;模式是一种行为型设计模式&#xff0c;用于在不破坏封装性的前提下&#xff0c;捕获并外部化一个对象的内部状态&#xff0c;以便在之后能够将该对象恢复到原先保存的状态。它广泛应用于需要实现撤销&#xff08;Undo&am…

数据结构(6)单链表算法题(下)

一、环形链表Ⅰ 1、题目描述 https://leetcode.cn/problems/linked-list-cycle 2、算法分析 思路&#xff1a;快慢指针 根据上图所示的流程&#xff0c;我们可以推测出这样一个结论&#xff1a;若链表带环&#xff0c;快慢指针一定会相遇。 那么&#xff0c;这个猜测是否正…

智能制造,从工厂建模,工艺建模,柔性制造,精益制造,生产管控,库存,质量等多方面讲述智能制造的落地方案。

智能制造&#xff0c;从工厂建模&#xff0c;工艺建模&#xff0c;柔性制造&#xff0c;精益制造&#xff0c;生产管控&#xff0c;库存&#xff0c;质量等多方面讲述智能制造的落地方案。

Qt 分裂布局:QSplitter 使用指南

在 GUI 开发中&#xff0c;高效管理窗口空间是提升用户体验的关键。QSplitter 作为 Qt 的核心布局组件&#xff0c;让动态分割窗口变得简单直观。一、QSplitter 核心功能解析 QSplitter 是 Qt 提供的布局管理器&#xff0c;专用于创建可调节的分割区域&#xff1a; 支持水平/垂…

R语言与作物模型(DSSAT模型)技术应用

R语言在DSSAT模型的气候、土壤、管理措施等数据准备&#xff0c;自动化模拟和结果分析上都发挥着重要的作用。一&#xff1a;DSSAT模型的高级应用 1.作物模型的概念 2.DSSAT模型发展现状 3.DSSAT与R语言的安装 4.DSSAT模型的高级应用案例 5.R语言在作物模型参数优化中的应用 6.…

JavaSE:学习输入输出编写简单的程序

一、打印输出到屏幕 Java提供了三种核心输出方法&#xff0c;适合不同场景&#xff1a; System.out.println() 打印内容后 自动换行 System.out.println("Welcome"); System.out.println("to ISS"); // 输出&#xff1a; // Welcome // to ISSSystem.out…

访问者模式感悟

访问者模式 首先有两个东西: 一个是访问者vistor (每一个访问者类都代表了一类操作) 一个是被访问者entity (model /info/pojo/node等等这些都行)也就是是说是一个实体类 其操作方法被抽离给了其他类。 访问者模式的核心思想就是**“把操作从数据结构中分离出来,每种操作…

从零到部署:基于Go和Docker的全栈短链接服务实战(含源码)

摘要&#xff1a;本文将手把手带你使用Go语言&#xff0c;并遵循依赖倒置、分层架构等最佳实践&#xff0c;构建一个高性能、高可用的全栈短链接生成器。项目采用Echo框架、GORM、Redis、MySQL&#xff0c;并通过Docker和Docker Compose实现一键式容器化部署到阿里云服务器。文…

MyBatis_3

上一篇文章&#xff0c;我们学习了使用XML实现MyBatis进行增、删、查、改等操作&#xff0c;本篇文章&#xff0c;我们将学习#{ }和${ }获取方法参数的区别和使用MyBatisXML实现动态SQL语句。 #{ }和${ }的区别 在之前的文章中我们都是使用#{ }进行赋值&#xff0c;但实际上M…

智能图书馆管理系统开发实战系列(一):项目架构设计与技术选型

项目背景 智能图书馆管理系统&#xff08;ILMS&#xff09;是一个现代化的桌面应用程序&#xff0c;采用前后端分离架构&#xff0c;结合了Web技术的灵活性和桌面应用的用户体验。本项目从高保真原型设计开始&#xff0c;经过完整的软件开发生命周期&#xff0c;最终实现为一个…

应急前端“黄金3分钟”设计:极端场景下的操作界面极速搭建技术

摘要**地震突发&#xff0c;应急指挥系统的操作界面却因加载缓慢无法及时调取数据&#xff1b;火灾现场&#xff0c;消防员手持终端的操作步骤繁琐&#xff0c;延误救援时机。在分秒必争的极端场景中&#xff0c;传统前端操作界面为何频频 “掉链子”&#xff1f;怎样才能在 “…