vue3的组件通信v-model使用

一、组件通信

1.props =》 父向子传值

   props 主要用于父组件向子组件通信。再父组件中通过使用:msg='msg'绑定需要传给子组件的属性值,然后再在子组件中用props接收该属性值

方法一 普通方式:// 父组件 传值<child :msg1="msg1" :list="list"></child><script>import child from "./child.vue";import { ref, reactive } from "vue";export default {setup() {//基础类型传值const msg1 = ref("父组件传给子组件的msg1");// 复杂类型(数组或对象)传值const list = reactive(['苹果', '梨', '香蕉'])return {msg1,list}}}</script>// 子组件 接收
<template><ul ><li  v-for="i in list" :key="i">{{ i }}</li></ul>
</template>
<script>
export default {// props接受父组件传过来的值props: ["msg1", "list"],setup(props) {console.log(props);// { msg1:"父组件传给子组件的msg1", list:['苹果', '梨', '香蕉'] }},
}
</script>
方法二:使用setup语法糖// 父组件 传值
<child :msg="msg" :list="list">
</child>
<script setup>import child from "./child.vue";const list = reactive(['苹果', '梨', '香蕉'])const msg = ref("父组件传给子组件的值");
</script>// 子组件 接收
<template><ul ><li  v-for="i in list" :key="i">{{ i }}</li></ul>
</template>
<script setup>// 这里不需要在从vue中引入defineProps,直接用const props = defineProps({// 第一种写法msg: String,// 第二种写法list: {type: Array,default: () => [],}})console.log(props);
</script>
2.emit方式=>子向父传值defineEmits

   $emits也就是通过自定义事件传值 主要用于子组件向父组件传值

   在子组件的点击事件中 通过触发父组件中的自定义事件,把想传给父组件的信息以参数形式带过去 父组件便可拿到子组件传过来的值

// 子组件 派发
<template><button @click="handleClick">按钮</button>
</template>
<script setup>let infos = ref('还好');const emit = defineEmits(['myClick']);//emits 为 defineEmits 显示声明后的对象。
// defineEmits:如存在多个监听事件则为 defineEmits(['increase','myClick'])const handleClick = () => {// 触发父组件中的方法,并把值以参数的形式传过去emit('myClick', infos);emit('increase', ref('还好33'));};
</script>// 父组件 接收
<template><child @myClick="onMyClick"  @increase="onIncrease"></child>
</template>
<script setup>import child from "./child.vue";// 父组件接受到子组件传过来的值const onMyClick = (msg) => {console.log(msg);}const onIncrease = (msg) => {console.log(msg.value);
}
</script>
3.expose / ref=》父获取子得属性或方法

expose与ref 主要用于父组件获取子组件的属性或方法。在子组件中,向外暴露出属性或方法,父组件便可以使用 ref 获取到子组件身上暴露的属性或方法。

<template><div>父组件:拿到子组件的message数据:{{ msg }}</div><button @click="callChildFn">调用子组件的方法</button><hr /><Child ref="com" />
</template><script setup>import Child from './child.vue';const com = ref(null); // 通过 模板ref 绑定子组件const msg = ref('');onMounted(() => {// 在加载完成后,将子组件的 message 赋值给 msgmsg.value = com.value.message;});function callChildFn() {console.log(com.value, '====');// 调用子组件的 changeMessage 方法com.value.show();//  重新将 子组件的message 赋值给 msgmsg.value = com.value.message;}
</script>子组件:
<template><div> 子组件:</div>
</template>
<script setup>const message = ref('子组件传递得信息');const show = () => {console.log('子组件得方法');};defineExpose({message,show,});
</script>
4.attrs

attrs 主要用于子组件获取父组件中没有通过 props 接收的属性

<template><Child :msg1="msg1" :msg2="msg2" title="子组件" />
</template><script setup>import Child from './child.vue';const msg1 = ref('信息1');const msg2 = ref('信息2');
</script>子组件
<template><div> 子组件:{{ msg1 }}-{{ attrs.msg2 }}-{{ attrs.title }}</div>
</template>
<script setup>// 子组件接收msg1defineProps({msg1: String,});const attrs = useAttrs();// 因为子组件接收了msg1,所以打印的结果中不会包含msg1, { msg2:"信息1", title: "子组件" }// 如果子组件没有接收msg1,打印的结果就是 { msg1: "信息1", msg2:"信息12", title: "子组件" }console.log(attrs);
</script>
5.provide/inject

遇到多层传值时,使用 props 和 emit 的方式会显得比较笨拙。这时就可以用 provide 和 inject 了。
provide与inject 主要为父组件向子组件或多级嵌套的子组件通信。
provide:在父组件中可以通过 provide 提供需要向后代组件传送的信息。
inject:从父组件到该组件无论嵌套多少层都可以直接用 inject 拿到父组件传送的信息。

<template><div>------祖父组件---------</div><button @click="fn">改变location的值</button><br /><div>双向数据绑定:</div>姓名 {{ userInfos.username }}:<input v-model="userInfos.username" /><Child />
</template><script setup>import Child from './child.vue';let location = ref('传递祖父的参数');var userInfos = reactive({username: '张三',age: 20,});let fn = () => {location.value = '改变值';};provide('location', location);provide('userInfos', readonly(userInfos));
</script>子组件:
<template><div><Sun /></div>
</template><script>
import Sun from "./sun.vue";
</script>
孙组件:
<template><div><h5>-------------孙组件接受参数-------------</h5><div>1.祖父组件定义provide,孙组件inject接受:{{ location }}</div><p>用户信息: {{ userInfos.username }}</p><br /><br /><div>2.provide inject实现父子组件传值的时候,子组件改变数据也会影响父组件</div><br />姓名:<input v-model="userInfos.username" /></div>
</template>
<script setup>let location = inject('location');let userInfos = inject('userInfos');
</script>注意:增加readonly后,子组件修改后,不会影响到父组件类似安全的provide/inject
使用vue提供的injectionKey 类型工具来再不同的上下文中共享类型
context。tsimport { InjectionKey, Ref } from 'vue'export interface SetUser{name: stringage: number
}// 函数的的InjectionKey
export const setUserKey: InjectionKey<SetUser> = Symbol()父组件
<script setup>
import {setUserKey } from './context'
provide(setUserKey , { 
name: 'Karen', //如果输入1,那么类型就会报错
age: 20})
</script>子组件
<script setup>
import {setUserKey } from './context'
const user =inject(setUserKey)// 输出SetUser | undefined
if(user){
console.log(user.name)//Karen
}
</script>
6.readonly

获取一个对象 (响应式或纯对象) 或 ref 并返回原始代理的只读代理,不能给属性重新赋值。只读代理是递归的:访问的任何嵌套 property 也是只读的。
简单得理解:要确保父组件传递得数据不会被子孙组件更改时,增加readonly

7.v-model

v-model 是 Vue 的一个语法糖。在 Vue3 中的玩法就更多了

7-1 单个v-model绑定
<template><Child v-model="message" />
</template><script setup>import Child from './child.vue';const message = ref('父传给子');
</script>
子组件:
<template><div><button @click="handleClick">修改model</button>{{ modelValue }}</div>
</template>
<script setup>// 接收defineProps(['modelValue', // 接收父组件使用 v-model 传进来的值,必须用 modelValue 这个名字来接收]);const emit = defineEmits(['update:modelValue']); // 必须用 update:modelValue 这个名字来通知父组件修改值function handleClick() {// 参数1:通知父组件修改值的方法名// 参数2:要修改的值emit('update:modelValue', '子改变值');}
</script>
7-2 多个v-model绑定
<template><Child v-model:msg1="message1" v-model:msg2="message2" />
</template><script setup>import Child from './child.vue';const message1 = ref('水果1');const message2 = ref('水果2');
</script>
子组件:
<template><div><div><button @click="changeMsg1">修改msg1</button> {{ msg1 }}</div><div><button @click="changeMsg2">修改msg2</button> {{ msg2 }}</div></div>
</template>
<script setup>// 接收defineProps({msg1: String,msg2: String,});const emit = defineEmits(['update:msg1', 'update:msg2']);function changeMsg1() {emit('update:msg1', '蔬菜1');}function changeMsg2() {emit('update:msg2', '蔬菜2');}
</script>
7-3 v-model修饰符

v-model 还能通过 . 的方式传入修饰。v-model 有内置修饰符——.trim、.number 和 .lazy。但是,在某些情况下,你可能还需要添加自己的自定义修饰符。

<template><Child v-model.uppercasefn="message" />
</template><script setup>import Child from './child.vue';const message = ref('水果');
</script>
子组件:
<template><div><div>{{ modelValue }}</div></div>
</template>
<script setup>const props = defineProps(['modelValue', 'modelModifiers']);const emit = defineEmits(['update:modelValue']);onMounted(() => {console.log(props.modelModifiers, '自定义v-model 修饰符');// 判断有没有uppercasefn修饰符,有的话就执行 下面得方法 方法if (props.modelModifiers.uppercasefn) {emit('update:modelValue', '蔬菜');}});
</script>
8.插槽 slot

插槽可以理解为传一段 HTML 片段给子组件。子组件将 元素作为承载分发内容的出口。

8-1 默认插槽

插槽的基础用法非常简单,只需在 子组件 中使用 标签,就会将父组件传进来的 HTML 内容渲染出来。

<template><Child><div>渲染</div></Child>
</template>
子组件:
// Child.vue<template><div><slot></slot></div>
</template>
8-2 具名插槽

具名插槽 就是在 默认插槽 的基础上进行分类,可以理解为对号入座。

父组件需要使用 标签,并在标签上使用 v-solt: + 名称 。子组件需要在 标签里用 name= 名称 对应接收。

<template><Child><template v-slot:monkey><div>渲染</div></template><button>按钮</button></Child>
</template>
子组件:
<template><div><!-- 默认插槽 --><slot></slot><!-- 具名插槽 --><slot name="monkey"></slot></div>
</template>
8-3 作用域插槽
<template><!-- v-slot="{scope}" 获取子组件传上来的数据 --><!-- :list="list" 把list传给子组件 --><Child v-slot="{ scope }" :list="list"><div><div>{{ scope.name }}--职业:{{ scope.occupation }}</div><hr /></div></Child>
</template>
<script setup>import Child from './child.vue';const list = reactive([{ name: '鲁班', occupation: '辅助' },{ name: '貂蝉', occupation: '刺客和法师' },{ name: '虞姬', occupation: '射手' },]);
</script>
子组件:
<template><div><!-- 用 :scope="item" 返回每一项 --><slot v-for="item in list" :scope="item"></slot></div>
</template>
<script setup>defineProps({list: {type: Array,default: () => [],},});
</script>

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

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

相关文章

Dinky MySQLCDC 整库同步到 Doris

资源&#xff1a;flink 1.17.0、dinky 1.0.2、doris-2.0.1-rc04 问题&#xff1a;Cannot deserialize value of type int from String &#xff0c;detailMessageunknowndatabases &#xff0c;not a valid int value 2024-05-29 16:52:20.136 ERROR org.apache.doris.flink.…

最长公共子序列问题的求解

假设有两个字符串A和B&#xff0c;A字符串的组成为 A A 0 A 1 A 2 . . . . . . A n − 1 A A_0A_1A_2......A_{n-1} AA0​A1​A2​......An−1​ B B 0 B 1 B 2 . . . . . . B m − 1 BB_0B_1B_2......B_{m-1} BB0​B1​B2​......Bm−1​ 要寻找这两个字符串的公共子序列还…

MS Excel: 高亮当前行列 - 保持原有格式不被改变

本文使用条件格式VBA的方法实现高亮当前行列&#xff0c;因为纯VBA似乎会清除原有的高亮格式。效果如下&#xff1a;本文图省事就使用同一种颜色了。 首先最重要的&#xff0c;【选中你期望高亮的单元格区域】&#xff0c;比如可以全选当前sheet的全部区域 然后点击【开始】-【…

06.深入学习Java 线程

1 线程的状态/生命周期 Java 的 Thread 类对线程状态进行了枚举&#xff1a; public class Thread implements Runnable {public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;} } 初始(NEW)&#xff1a;新创建了一个线程对象&#xff0c;但还没有调用…

数据库学习笔记1-数据库实验1

文章目录 创建表格的时候出现的一些错误查询所有的表格实验一查询单个表格分块修改大学数据库表格创建大学数据库表格系课程教师课程段授课学生选课注意吐槽 修改大学数据库表格2&#xff08;英文版本&#xff09;abcde 自建项目-在线书店数据库 创建表格的时候出现的一些错误 …

子集和问题(回溯法)

目录 ​​​​ 前言 一、算法思路 二、分析过程 三、代码实现 伪代码&#xff1a; C&#xff1a; 总结 前言 【问题描述】考虑定义如下的PARTITION问题中的一个变型。给定一个n个整数的集合X{x1,x2,…,xn}和整数y&#xff0c;找出和等于y的X的子集Y。 一、算法思路 基本思想&am…

【STL】C++ stack(栈) 基本使用

目录 一 stack常见构造 1 空容器构造函数&#xff08;默认构造函数&#xff09; 2. 使用指定容器构造 3 拷贝构造函数 二 其他操作 1 empty 2 size 3 top 4 push && pop 5 emplace 6 swap 三 总结 一 stack常见构造 1 空容器构造函数&#xff08;默认构造…

云计算OpenStack基础

1.什么是虚拟化&#xff1f; •虚拟化是云计算的基础。 •虚拟化是指计算元件在虚拟的而不是真实的硬件基础上运行。 •虚拟化将物理资源转变为具有可管理性的逻辑资源&#xff0c;以消除物理结构之间的隔离&#xff0c;将物理资源融为一个整体。虚拟化是一种简化管理和优化…

探秘AI艺术:揭开Midjourney绘画的神秘面纱

在当今这个数字化迅速发展的时代&#xff0c;AI技术已经深入到我们生活的方方面面&#xff0c;而最令人着迷的莫过于它在艺术创作领域的应用。“Midjourney绘画”就是这样一个令人惊叹的例子&#xff0c;它通过高级AI技术&#xff0c;能够帮助用户生成独一无二的艺术作品。但是…

如何知道自己电脑的 Shell类型是什么?

在macOS中&#xff0c;你可以通过以下几种方法来确定当前正在使用的shell类型&#xff0c;并了解相关的配置文件&#xff1a; 1. 使用终端命令确定shell类型 打开终端应用程序&#xff08;Terminal&#xff09;。输入以下命令并按回车键&#xff1a;echo $SHELL。该命令会输出…

最长递增子序列,交错字符串

第一题&#xff1a; 代码如下&#xff1a; int lengthOfLIS(vector<int>& nums) {//dp[i]表示以第i个元素为结尾的最长子序列的长度int n nums.size();int res 1;vector<int> dp(n, 1);for (int i 1; i < n; i){for (int j 0; j < i; j){if (nums[i]…

[日常开发] 数据库主从延迟问题

MySQL数据库主从延迟问题 无论是学习还是工作中&#xff0c;MySQL数据库的使用都十分地广泛。在业务中&#xff0c;数据库也会以集群的形式使用&#xff0c;所以会涉及到主从问题。 问题描述 在使用MySQL数据库的时候&#xff0c;在service的方法中首先向A数据表批量插入了数…

Spring-注解

Spring 注解分类 Spring 注解驱动模型 Spring 元注解 Documented Retention() Target() // 可以继承相关的属性 Inherited Repeatable()Spirng 模式注解 ComponentScan 原理 ClassPathScanningCandidateComponentProvider#findCandidateComponents public Set<BeanDefin…

动态规划part03 Day43

LC343整数拆分&#xff08;未掌握&#xff09; 未掌握分析&#xff1a;dp数组的含义没有想清楚&#xff0c;dp[i]表示分解i能够达到的最大乘积&#xff0c;i能够如何分解呢&#xff0c;从1开始遍历&#xff0c;直到i-1&#xff1b;每次要不是j和i-j两个数&#xff0c;要不是j和…

【传知代码】自监督高效图像去噪(论文复现)

前言&#xff1a;在数字化时代&#xff0c;图像已成为我们生活、工作和学习的重要组成部分。然而&#xff0c;随着图像获取方式的多样化&#xff0c;图像质量问题也逐渐凸显出来。噪声&#xff0c;作为影响图像质量的关键因素之一&#xff0c;不仅会降低图像的视觉效果&#xf…

串口通信问题排查总结

串口通信问题排查 排查原则&#xff1a; 软件从发送处理到接收处理&#xff0c;核查驱动、控制及发送接收数据是否正常。硬件从发送到接收&#xff0c;针对信号经过的各段&#xff0c;分段核对信号是否正常。示波器、逻辑分析仪。用万用表、示波器、逻辑分析仪等工具&#xf…

JRT性能演示

演示视频 君生我未生&#xff0c;我生君已老&#xff0c;这里是java信创频道JRT&#xff0c;真信创-不糊弄。 基础架构决定上层建筑&#xff0c;和给有些品种的植物种植一样&#xff0c;品种不对&#xff0c;施肥浇水再多&#xff0c;也是不可能长成参天大树的。JRT吸收了各方…

基于文本来推荐相似酒店

基于文本来推荐相似酒店 查看数据集基本信息 import pandas as pd import numpy as np from nltk.corpus import stopwords from sklearn.metrics.pairwise import linear_kernel from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extrac…

C++:类和对象

一、前言 C是面向对象的语言&#xff0c;本文将通过上、中、下三大部分&#xff0c;带你深入了解类与对象。 目录 一、前言 二、部分&#xff1a;上 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实例化 7.类的…

JavaScript条件语句与逻辑判断:解锁代码逻辑的奥秘【含代码示例】

JavaScript条件语句与逻辑判断&#xff1a;解锁代码逻辑的奥秘【含代码示例】 基本概念与作用if...else&#xff1a;决策的基础switch&#xff1a;多路分支的能手逻辑运算符&#xff1a;连接逻辑的纽带三元运算符&#xff1a;简洁的力量 功能使用思路与技巧短路求值优化防止swi…