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控制流:循环(本文) 通过第二章…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
多模态学习路线(2)——DL基础系列
目录 前言 一、归一化 1. Layer Normalization (LN) 2. Batch Normalization (BN) 3. Instance Normalization (IN) 4. Group Normalization (GN) 5. Root Mean Square Normalization(RMSNorm) 二、激活函数 1. Sigmoid激活函数(二分类&…...
dvwa11——XSS(Reflected)
LOW 分析源码:无过滤 和上一关一样,这一关在输入框内输入,成功回显 <script>alert(relee);</script> MEDIUM 分析源码,是把<script>替换成了空格,但没有禁用大写 改大写即可,注意函数…...
MySQL 数据库深度剖析:事务、SQL 优化、索引与 Buffer Pool
在当今数据驱动的时代,数据库作为数据存储与管理的核心,其性能与可靠性至关重要。MySQL 作为一款广泛使用的开源数据库,在众多应用场景中发挥着关键作用。在这篇博客中,我将围绕 MySQL 数据库的核心知识展开,涵盖事务及…...
JS面试常见问题——数据类型篇
这几周在进行系统的复习,这一篇来说一下自己复习的JS数据结构的常见面试题中比较重要的一部分 文章目录 一、JavaScript有哪些数据类型二、数据类型检测的方法1. typeof2. instanceof3. constructor4. Object.prototype.toString.call()5. type null会被判断为Obje…...
【技术笔记】MSYS2 指定 Python 版本安装方案
#工作记录 MSYS2 指定 Python 版本安装 一、前置条件 安装指定版本需要在干净的 MSYS2 环境中执行,为保证工具链的兼容性,若已安装 Python,需先卸载 Python 及与该版本深度绑定的工具链。具体操作如下: 卸载 Python:…...
Python爬虫:trafilatura 的详细使用(快速提取正文和评论以及结构,转换为 TXT、CSV 和 XML)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、trafilatura 概述1.1 trafilatura介绍1.2 亮点特色1.3 安装二、基本使用2.1 从URL直接提取内容2.2 输出格式控制2.3 从HTML字符串提取2.4 使用命令行工具三、高级功能3.1 全局设置3.2 提取参数定制3.3 多线程批量处…...
Secs/Gem第十二讲(基于secs4net项目的ChatGpt介绍)
好,那我们进入最关键的一讲—— 第十二讲:完整事件通知流程全景图——CEID 触发到主机接收的全过程 关键词:CEID 事件上报、S6F11 报文、事件触发流程、数据驱动机制、Report Dispatch、主机解析流程 本讲目标 你将彻底理解: 设…...
