Vue3父子组件传属性和方法调用Demo

Vue3父子组件传属性和方法调用Demo

  • 说明
  • 目录
  • 父组件给子组件传值和方法
    • 父组件给子组件传值-使用defineProps接受父组件属性值
    • 父组件给子组件传值-使用defineModel接受父组件v-model值
      • 当子组件只需要接收父组件一个v-model值时,写法1如下:
      • 子组件接收单个v-model写法2如下:
      • 当子组件需要接收父组件多个v-model值时,写法如下:
    • 父组件给子组件传方法
  • 子组件调用父组件方法-使用defineEmits调用父组件方法
  • 子组件暴露属性和方法给父组件调用-使用defineExpose暴露子组件属性和方法

说明

这里记录下自己学习Vue3父子组件怎么传值和方法怎么互相调用,防止后面继续踩坑且方便以后直接使用。这里承接自己的博客Vue3+vite优化基础架构(3)— 优化vue-i18n国际化配置这篇博客,在该博客项目的基础上学习Vue3父子组件传值及使用。

官方文档:https://cn.vuejs.org/api/sfc-script-setup.html#defineprops-defineemits

目录

在这里插入图片描述
这里父组件是test-management1文件夹下的index.vue,子组件是test-management1文件夹下的components文件夹的test-child.vue。

父组件给子组件传值和方法

父组件给子组件传属性值,有2种方式:

  1. 第一种方式是在子组件里面使用defineProps来接受父组件那边传过来的属性值。
  2. 第二种方式是在子组件里面使用defineModel来接受父组件那边传过来的v-model值。

父组件给子组件传值-使用defineProps接受父组件属性值

父组件代码如下:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传参,参数为name,age,isOpenEmail,content,score这5--><TestChild:name="testName":age="testAge":isOpenEmail="testIsOpenEmail":content="testContent":score="testScore"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义name值const testName=ref('张三')//定义age值const testAge=ref(18)//定义isOpenEmail开通邮箱值const testIsOpenEmail=ref(false)//定义content值const testContent=ref(['测试值1','测试值2','测试值3'])//定义score值const testScore=ref({curriculum:"语文",score:60})
</script><style scoped></style>

子组件代码如下:

<template><!--显示父组件传过来的参数值--><div><!--在页面模版里面如果要使用父组件里面穿过来的参数,有2种写法,都能在页面显示出来:--><!--第一种全写:{{props.name}}--><div>name名字为:{{props.name}}</div><!--第二种简写:{{name}},这种简写有个问题,如果你在js中定义了一个相同名的参数,它会优先读取定义的那个参数,不会去读父组件传过来的参数--><div>name名字为:{{name}}</div><div>age年龄为:{{props.age}}</div><div>isOpenEmail是否开通邮箱为:{{props.isOpenEmail}}</div><div>content内容为:{{props.content[0]}}</div><div>score分数为:{{props.score.score}}</div></div>
</template><script setup>import {onMounted} from 'vue'//const name="haha"//页面初始化时执行onMounted(() => {console.info("从父组件那边传过来的值为:")console.info("name:",props.name)console.info("age:",props.age)console.info("isOpenEmail:",props.isOpenEmail)console.info("content:",props.content)console.info("score:",props.score)})//使用defineProps接收父组件穿传过来的参数const props = defineProps({//从父组件那边接收一个String类型的参数,参数名叫name(名字)name: {required:false,//是否必须传该name参数,不写默认为false,true为必须传该参数,false为可以不传该name参数type: String,//参数类型为String字符串default: ''//默认值为空值},//从父组件那边接收一个Number类型的参数,参数名叫age(年龄)age: {type: Number,//参数类型为Number整型default: 0//默认值为0},//从父组件那边接收一个Boolean类型的参数,参数名叫isOpenEmail(是否开通邮箱)isOpenEmail: {type: Boolean,//参数类型为Boolean布尔类型default: false//默认值为false},//从父组件那边接收一个content类型的参数,参数名叫content(内容)content: {type: Array,//参数类型为Array数组类型default: []//默认值为空数组},//从父组件那边接收一个Object类型的参数,参数名叫score(分数)score: {type: Object,//参数类型为Object对象类型default: {}//默认值为空对象}})
</script><style scoped></style>

谷歌浏览器效果显示
在这里插入图片描述
注意事项
1.在页面模版中如果直接使用简写{{name}}这种写法,如果在js中又重新定义了一个name属性,那么会优先使用定义的这个name值,不会使用父组件那边传值过来的name属性值。如下:
在这里插入图片描述
在这里插入图片描述

2.如果子组件接收的参数有required属性而且为true,如果父组件不传该属性的话,那么控制台会出现警告。如下:
在这里插入图片描述
在这里插入图片描述
浏览器结果如下:
在这里插入图片描述

父组件给子组件传值-使用defineModel接受父组件v-model值

当子组件只需要接收父组件一个v-model值时,写法1如下:

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传参,使用v-model形式进行双向绑定--><TestChildv-model="testName"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义name值const testName=ref('张三')</script><style scoped></style>

子组件代码:

<template><!--显示父组件传过来的参数值--><div><el-input v-model="modelValue"></el-input></div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {})//直接使用解构写法来接收父组件那边通过v-model传过来的值,必须使用modelValue来接收属性值const [modelValue]=defineModel()console.info("子组件接收父组件的name值为:",modelValue.value)
</script><style scoped></style>

谷歌浏览器结果如下:
在这里插入图片描述

子组件接收单个v-model写法2如下:

<template><!--显示父组件传过来的参数值--><div><el-input v-model="name"></el-input></div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {console.info("子组件接收父组件的v-model值为:",name.value)})//直接使用defineModel接受父组件通过v-model传过来的值//子组件这边定义一个name属性来接收父组件那边传过来的v-model的值,简写形式如下const name=defineModel()//完整写法/*const name = defineModel({type: String,//字段类型default: ''//默认空值})*///等同于上面的default: ''写法/*const name = defineModel({type: String,//字段类型default: () => {//扩展:将默认属性作为一个方法使用,可以执行一段自定义逻辑,这里直接返回了一个空值,等同于上面写法return ''}})*/</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述

当子组件需要接收父组件多个v-model值时,写法如下:

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传参,使用v-model形式进行双向绑定--><!--绑定多个v-model时,v-model冒号后面为参数名称,后面为参数值--><!--向子组件传参属性为testName,testAge,testIsOpenEmail,testContent,testScore这5个参数--><TestChildv-model:testName="name"v-model:testAge="age"v-model:testIsOpenEmail="isOpenEmail"v-model:testContent="content"v-model:testScore="score"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义name值const name=ref('张三')//定义age值const age=ref(18)//定义isOpenEmail开通邮箱值const isOpenEmail=ref(false)//定义content值const content=ref(['测试值1','测试值2','测试值3'])//定义score值const score=ref({curriculum:"语文",score:60})</script><style scoped></style>

子组件代码:

<template><!--显示父组件传过来的参数值--><div><!--使用父组件那边传过来的name值--><el-input v-model="name"></el-input></div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {console.info("子组件接收父组件的v-model值为:")console.info("name:",name.value)console.info("age:",age.value)console.info("isOpenEmail:",isOpenEmail.value)console.info("content:",content.value)console.info("score:",score.value)})//直接使用defineModel接受父组件通过v-model传过来的值//子组件这边自定义一个name属性来接收父组件那边传过来的v-model(testName)的值,简写形式如下const name=defineModel('testName')//完整写法/*const name = defineModel('testName',{type: String,//字符串类型default: ''//默认值为空})*///子组件这边自定义一个age属性来接收父组件那边传过来的v-model(testAge)的值const age = defineModel('testAge',{type: Number,//整型类型default: 0//默认值为0})//子组件这边自定义一个isOpenEmail属性来接收父组件那边传过来的v-model(testIsOpenEmail)的值const isOpenEmail = defineModel('testIsOpenEmail',{type: Boolean,//布尔类型default: false//默认值为false})//子组件这边自定义一个content属性来接收父组件那边传过来的v-model(testContent)的值const content = defineModel('testContent',{type: Array,//数组类型default: []//默认值为空数组})//子组件这边自定义一个score属性来接收父组件那边传过来的v-model(testScore)的值const score = defineModel('testScore',{type: Object,//对象类型default: {}//默认值为空对象})
</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述

父组件给子组件传方法

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传递一个方法,方法名为print--><TestChild:print="testPrint"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义print方法const testPrint = () => {console.info("我是父组件的testPrint方法。")}
</script><style scoped></style>

子组件代码:

<template><!--显示父组件传过来的参数值--><div>子组件</div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {//调用父组件那边传过来的方法props.print()})//使用defineProps接受父组件穿传过来的参数const props = defineProps({//从父组件那边接收一个方法,参数名叫printprint: {type: Function,//参数类型为Function方法类型default: () =>{}//默认一个空方法}})</script><style scoped></style>

谷歌浏览器结果如下:
在这里插入图片描述

子组件调用父组件方法-使用defineEmits调用父组件方法

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--自定义一个testChange方法--><TestChild@testChange="change"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//父组件定义一个change方法const change = (val) => {console.info("我是父组件的change方法,参数值为:",val)}</script><style scoped></style>

子组件代码:

<template><!--子组件--><div>我是子组件<!--不使用js的话,模版页面直接调用父方法并传递参数写法如下:-->
<!--    <el-button @click="$emit('testChange','2222')"></el-button>--></div>
</template><script setup>//使用defineEmits接收父组件自定义的testChange方法const emit=defineEmits(['testChange'])//子组件调用父组件中的testChange方法,并给该方法传递了一个参数值为2222emit('testChange', '2222')
</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述

子组件暴露属性和方法给父组件调用-使用defineExpose暴露子组件属性和方法

子组件代码:

<template><!--子组件--><div><div>name名字为:{{name}}</div><div>age年龄为:{{age}}</div><div>isOpenEmail是否开通邮箱为:{{isOpenEmail}}</div><div>content内容为:{{content}}</div><div>score分数为:{{score}}</div></div>
</template><script setup>import {ref} from "vue"//定义name值const name=ref('张三')//定义age值const age=ref(18)//定义isOpenEmail开通邮箱值const isOpenEmail=ref(false)//定义content值const content=ref(['测试值1','测试值2','测试值3'])//定义score值const score=ref({curriculum:"语文",score:60})//测试方法const test = (val) => {console.info("我是子组件的test方法,参数值是=",val)}//使用defineExpose暴露属性和方法,暴露了name,age,isOpenEmail,content,score这5个属性值和1个test方法给父组件调用defineExpose({name,age,isOpenEmail,content,score,test})
</script><style scoped></style>

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--如果子组件里面暴露了属性和方法,子组件必须要加ref才能在父组件中调用子组件里面的属性和方法--><TestChild ref="testChildRef"/></div>
</template><script setup name="test-management1">import {ref,onMounted} from "vue"//引入子组件import TestChild from './components/test-child.vue'//页面初始化加载onMounted(() => {//调用子组件里面的暴露的属性和方法,要用ref去调用console.info("父组件中调用子组件中属性值:")console.info("name值:",testChildRef.value.name)console.info("age值:",testChildRef.value.age)console.info("isOpenEmail值:",testChildRef.value.isOpenEmail)console.info("content值:",testChildRef.value.content)console.info("score值:",testChildRef.value.score)console.info("父组件中调用子组件中方法:")testChildRef.value.test('111')})//子组件ref名称const testChildRef=ref()</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述
注意事项
如果父组件中调用了子组件未暴露的属性或者方法或者不存在的属性和方法,那么浏览器控制台会报错,如下:
在这里插入图片描述
在这里插入图片描述
父子组件的传值和方法互相调用就学习到这里了,后面要是遇到新的方式在扩展。

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

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

相关文章

海尔智家三翼鸟:从家电到场景,能否跨越智能化陷阱?

在智能家居浪潮的席卷之下&#xff0c;三翼鸟作为海尔智家旗下的场景品牌&#xff0c;曾一度被视为传统家电厂商转型升级的典范。然而&#xff0c;在光鲜亮丽的宣传背后&#xff0c;三翼鸟正逐步暴露出难以忽视的困境与挑战&#xff0c;其智能化之路似乎并不如预期般顺畅。 从用…

微软:云服务大规模宕机因DDoS“防卫过当”

杀毒软件导致全球蓝屏&#xff0c;DDoS防护导致云服务宕机&#xff0c;微软这家全球最大的网络安全公司&#xff0c;正在不断刷新人们对“安全威胁”的认知。 微软本周三晚间宣布&#xff0c;本周二全球范围内多个Microsoft 365和Azure云服务大规模长时间宕机事件的原因&#…

AI大模型应用(2)ChatGLM3本地部署及其在alpaca_zh数据集上的低精度微调

AI大模型应用(2)ChatGLM3部署及其在alpaca_zh数据集上的低精度微调 我们之前已经了解了HuggingFace中peft库的几种高效微调方法。 参数高效微调PEFT(一)快速入门BitFit、Prompt Tuning、Prefix Tuning 参数高效微调PEFT(二)快速入门P-Tuning、P-Tuning V2 参数高效微调PEFT…

deepseek杀疯了,偷摸开源全球一梯队大模型——DeepSeek-V2-Chat-0628

就在今年6月&#xff0c;深度求索团队发布了DeepSeek-V2模型后不久&#xff0c;新版本DeepSeek-V2-Chat-0628 模型也在7月开源了。其推理能力有了极大提升。尤其在数学解题、逻辑推理、编程、指令跟随、Json格式输出不同维度上&#xff0c;最高有16%的性能提升。 在Arena-Hard…

推荐一款前端滑动验证码插件(Vue、uniapp)

uniapp版本&#xff1a;滑块拼图验证码&#xff0c;有后端&#xff0c;简单几步即可实现&#xff0c;小程序、h5都可以用 - DCloud 插件市场 Vue版本及cdn版本可以查阅文档&#xff1a; 行为验证 | Poster 文档 示例代码&#xff1a; <template><view id"app&…

YesPlayMusic本地服务器部署并实现远程在线访问听歌

文章目录 前言1. 安装Docker2. 本地安装部署YesPlayMusic3. 安装cpolar内网穿透4. 固定YesPlayMusic公网地址 前言 本文主要介绍如何在本地快速搭建YesPlayMusic云音乐播放器&#xff0c;并且结合cpolar内网穿透工具实现随时随地远程访问局域网内的音乐播放器听歌。 YesPlayM…

保研408真题练习:2009年全国硕士研究生入学统一考试(单选篇2)

&#x1f9ca;&#x1f9ca;&#x1f9ca;单项选择题&#xff08;共40道&#xff09; &#x1f9ca;操作系统&#xff08;8道&#xff09; &#x1f965;1.进程调度算法 高响应比优先调度&#xff1a;选出响应比最高的进程投入执行&#xff0c;响应比R(等待时间&#xff0b;执…

排序算法:归并排序,golang实现

目录 前言 归并排序 代码示例 1. 算法包 2. 归并排序代码 3. 模拟程序 4. 运行程序 5. 从大到小排序 归并排序主要操作 1. 合并 2. 分割&#xff08;Divide&#xff09;与递归排序&#xff08;Conquer&#xff09; 总体思想 循环次数测试 假如 10 条数据进行排序…

10、billu-b0x2

难度 中 目标 root权限 首先确定靶机ip地址 netdiscover -i eth0 -r 192.168.189.0/24 kali 192.168.189.58 靶机 192.168.189.184 信息收集端口扫描 看到一个80和8080&#xff0c;先重点摸一下网站的内容 然后看到信息里有个robots.txt 首先就去访问一下 看到有许多不允许…

【C语言】数组和函数实践:扫雷游戏

扫雷游戏 1. 扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 ⽂件结构设计 2. 扫雷游戏的代码实现&#xff08;1&#xff09;菜单menu函数&#xff08;2&#xff09;设计main函数&#xff08;3&#xff09;设计game函数&#xff08;4…

华为od机试真题:求幸存数之和(Python)

2024华为OD机试&#xff08;C卷D卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 给一个正整数列nums&#xff0c;一个跳数jump&#xff0c;及幸存数量left。运算过程为:从索引为0的位置开始向后跳&#xff0c;中间跳过 J 个数字&#xff0c;命中索引为 J1的数…

腾讯云短信服务的开通流程

目录 一、开通服务二、创建secretId和secretKey三、创建应用四、创建实名资质五、创建签名六、创建正文模板一、开通服务 从控制台进入短信模块,点击【开始接入】开通服务: 认证主体首次开通短信服务可获赠国内短信,免费试用: 二、创建secretId和secretKey 创建链接:…

创意无限:11个设计圈热议的UI设计灵感网站集锦

无论你是一个经验丰富的UI设计师还是一个新的UI设计师&#xff0c;拥有一些高质量、可靠的UI设计网站灵感库都能加速你的设计过程。借助灵感资源&#xff0c;您可以更快、更有效地启动该项目。与此同时&#xff0c;优秀的UI设计网站也能帮助您探索新的设计解决方案&#xff0c;…

个性化你的生产力工具:待办事项App定制指南

国内外主流的10款待办事项软件对比&#xff1a;PingCode、Worktile、滴答清单、番茄ToDo、Teambition、Todoist、Microsoft To Do、TickTick、Any.do、Trello。 在寻找合适的待办事项软件时&#xff0c;你是否感到选择众多、难以决断&#xff1f;一个好的待办事项工具可以大大提…

【C++BFS】802. 找到最终的安全状态

本文涉及知识点 CBFS算法 LeetCode802. 找到最终的安全状态 有一个有 n 个节点的有向图&#xff0c;节点按 0 到 n - 1 编号。图由一个 索引从 0 开始 的 2D 整数数组 graph表示&#xff0c; graph[i]是与节点 i 相邻的节点的整数数组&#xff0c;这意味着从节点 i 到 graph…

专硕复试线298/295!哈尔滨理工大学计算机考研考情分析!

哈尔滨理工大学&#xff08;Harbin University of Science and Technology&#xff09;&#xff0c;位于哈尔滨市&#xff0c;是黑龙江省人民政府与国家国防科技工业局共建高校&#xff0c;入选“中西部基础能力建设工程”高校、国家“特色重点学科项目”建设高校、教育部“卓越…

MCU单片机GPIO初始化该按什么顺序配置?为什么初始化时有电平跳变?

GPIO初始化时有时钟配置、模式配置、输出配置、复用配置&#xff0c;那么在编写初始化代码时&#xff0c;到底该按什么顺序执行呢&#xff1f;如果顺序不当那初始化过程可能会出现短暂的电平跳变。 第一步&#xff0c;初始化MCU外设时&#xff0c;一般都需要先打开对应寄存器的…

【Qwen-Audio部署实战】Qwen-Audio-Chat模型之对话机器人部署测试

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

【Hot100】LeetCode—169. 多数元素

目录 题目1- 思路2- 实现⭐169. 多数元素——题解思路 3- ACM 实现 题目 原题连接&#xff1a;169. 多数元素 1- 思路 定义两个变量 一个是 count&#xff1a;维护当前元素的出现次数一个是 ret &#xff1a;维护当前元素 思路 遍历整个数组**①如果 count 0 **&#xff…

【TS】TypeScript中的接口(Interface):对象类型的强大工具

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 TypeScript中的接口(Interface):对象类型的强大工具引言1. 接口的基本概念1.1 什…