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种方式:
- 第一种方式是在子组件里面使用defineProps来接受父组件那边传过来的属性值。
- 第二种方式是在子组件里面使用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>
浏览器结果如下:

注意事项
如果父组件中调用了子组件未暴露的属性或者方法或者不存在的属性和方法,那么浏览器控制台会报错,如下:


父子组件的传值和方法互相调用就学习到这里了,后面要是遇到新的方式在扩展。
相关文章:
Vue3父子组件传属性和方法调用Demo
Vue3父子组件传属性和方法调用Demo 说明目录父组件给子组件传值和方法 父组件给子组件传值-使用defineProps接受父组件属性值父组件给子组件传值-使用defineModel接受父组件v-model值 当子组件只需要接收父组件一个v-model值时,写法1如下:子组件接收单个v-model写法2如下:当子…...
aac怎么转为mp3?操作起来很简单的几种aac转mp3的方法
aac怎么转为mp3?aac格式的优势主要体现在音质和压缩效率,尤其是在较低比特率下,能够实现更清晰的音质,这也是为何许多现代设备和应用偏爱aac格式的原因之一。特别是在手机、平板以及智能音响等设备中,aac文件几乎可以无…...
结合mybatis-plus实现Function获取java实体类的属性名
1、工具类 package com.yh.tunnel.util;import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.google.common.base.CaseFormat; import com.yh.tunnel.domain.Plan;import java.lang.invoke.SerializedLambda; import java.lang.reflect.Field; import…...
vue 响应式数据原理
发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 Vue 的响应式数据原理是其核心功能之一,它使得 Vue 应用能够自动响应数据的变化,并在数据变化时自动更新…...
android 计算CRC
<?php /** * 将一个字符按比特位进行反转 eg: 65 (01000001) --> 130(10000010) * param $char * return $char */ function reverseChar($char) { $byte ord($char); $tmp 0; for ($i 0; $i < 8; $i) { if ($byte & (1 << $i)…...
Linux tinyproxy 使用教程
简介 Tinyproxy 是一款轻量级 HTTP 代理服务器,使用最少的资源,非常适合硬件有限的系统。尽管体积小,但它可以处理大量流量,而不会出现明显的性能问题。旨在处理简单的代理任务。它通常用于路由网络流量以保护隐私、缓存或访问受…...
局部规划器设计思路
本文参考知乎文章:如何设计局部规划器 0 引言 局部规划器设计通用方法:生成路径——>寻找最优路径——>后处理优化 1 路径生成 四个问题: ① 如果全局路径中突然出现动态障碍物 ② 如果全局路径非常靠近障碍物 ③ 如果全局路径不容易跟踪(B样条平滑) ④ 如果全局…...
数字图像处理技术期末复习
1. 已知图像的分辨率和深度,怎么求图像的存储空间(位,字节,KB)? 题目: 已知图像的分辨率和深度,怎么求图像的存储空间(位,字节,KB)&a…...
UITableView显示数据,增加数据,删除数据及移动数据行
UITableView和html中的table有点类似的,也有header和footer和body,row。下面给出一个demo // // TableViewTestViewController.m // iosstudy2024 // // Created by figo on 2024/12/9. //#import "TableViewTestViewController.h"interfa…...
金智塔科技喜获CCF中国数字金融大会 GraphRAG竞赛二等奖
12月7日,CCF 首届中国数字金融大会GraphRAG竞赛在上海落下帷幕,金智塔科技(团队名称:塔塔向前冲)从众多参赛队伍中脱颖而出,喜获二等奖。 CCF 首届中国数字金融大会由中国计算机学会主办,中国计…...
方案解读:数字化扩展中如何提升多云应用安全能力?
越来越多企业选择上云,拥抱数字化转型。数据显示,在过去一年中,将应用托管至六种不同环境中的企业比例已经翻倍,达到令人震惊的38%。与此同时,应用和流经其的关键数据已成为日益复杂的网络攻击的首选目标,且…...
“年轻科技旗舰”爱玛A7 Plus正式发布,全国售价4999元
12月18日,备受行业瞩目的“A7上场 一路超神”爱玛旗舰新品发布会在爱玛台州智造工厂盛大举行。 作为年末“压轴产品”的“两轮豪华轿跑”爱玛A7Plus重磅上场,以“快、稳、帅、炫、智、爽”六大超神技惊艳四座,不仅践行了爱玛科技的精品战略&…...
oracle开窗函数笔记、over()笔记
文章目录 开窗函数、组函数、分析函数概念聚合函数和分析函数的区别partition by后面也可以跟多个字段 开窗函数一定要加 聚合函数、或分析函数吗,否则会报错lag()和lead()的用法lag和lead实战开窗函数可以和其他函数一起使用吗? TODO开窗函数中的count(1)是什么意…...
【HarmonyOS】HarmonyOS 和 Flutter混合开发 (一)之鸿蒙Flutter环境安装
【HarmonyOS】HarmonyOS 和 Flutter混合开发 (一)之鸿蒙Flutter环境安装 一、前言 flutter作为开源适配框架方案,已经在Android,IOS,Web,Window四大平台进行了适配,一套代码,可以同…...
海外招聘丨卢森堡大学—人工智能和机器学习中的 PI 用于图像分析
雇主简介 卢森堡大学立志成为欧洲最受推崇的大学之一,具有鲜明的国际化、多语言和跨学科特色。 她促进研究和教学的相互影响,与国家息息相关,因其在特定领域的研究和教学而闻名于世,并成为当代欧洲高等教育的创新典范。 她的核…...
LeetCode hot100-85
https://leetcode.cn/problems/coin-change/?envTypestudy-plan-v2&envIdtop-100-liked 322. 零钱兑换 已解答 中等 相关标签 相关企业 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑…...
linux 内核数据包处理中的一些坑和建议
1、获取IP头部 iph ip_hdr(skb); struct sk_buff { ...... sk_buff_data_t transport_header; /* Transport layer header */ sk_buff_data_t network_header; /* Network layer header */ sk_buff_data_t mac_header; /* Link layer header */ ...... } 1࿰…...
C++ 的衰退复制(decay-copy)
目录 1.什么是衰退复制(decay-copy) 1.1.推导规则 1.2.LWG issue 929 1.3.想象中的 decay_copy 2.decay-copy 与 auto 2.1.为什么引入衰退复制 2.2. 成为 C 23 的语言特性 3.应用场景 4.总结 1.什么是衰退复制(decay-copy࿰…...
vue-cli 5接入模块联邦 module federation
vue-cli 5接入模块联邦 module federation 模块联邦概念实现思路配置遇到的问题: 模块联邦概念 模块联邦由webpack 5最先推出的,让应用加载远程的代码模块来实现不同的Web应用共享代码片段.模块联邦分为两个角色,一个是生产者,一个是消费者.生产者暴露代码供消费者消费 (用一个…...
【Rust自学】3.6. 控制流:循环
3.6.0. 写在正文之前 欢迎来到Rust自学的第三章,一共有6个小节,分别是: 变量与可变性数据类型:标量类型数据类型:复合类型函数和注释控制流:if else控制流:循环(本文) 通过第二章…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
