Vue3 setup语法父子组件变量方法调用

server/2024/10/18 5:38:36/

一、简述

setup语法<script setup> 的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露。

当父组件通过模板引用获取到了该组件的实例时,得到的实例类型为 { a: number, b: number } (ref 都会自动解包,和一般的实例一样)

二、父组件调用子组件方法/变量

1.子组件[defineExpose]

<template><div>子组件</div>
</template><script setup>
// 第1步:定义子组件的方法
const getUserName = (userId) => {console.log(userId)
}
// 第1步:定义子组件的变量
const userVO = ref()
// 第2步:暴露方法
defineExpose({getUserName,userVO
})
</script>

2.父组件

<template><!--第2步 在引用子组件时,定义ref引用--><child ref="childRef" />
</template>
<script setup>
import Child from './components/child.vue'
// 第1步 定义子组件引用变量
const childRef = ref(null)
// 第3步 调用子组件方法/变量
const getChildMethodOrValue = () => {// 调用子组件的方法或者变量,通过valuechildRef.value.getUserName(8);// 这里子组件userVO会自动拆包,不用使用userVO.valueconsole.log('调用子组件的变量',childRef.value.userVO)
}
</script>

三、子组件调用父组件方法/变量

1.方法调用

1.1.父组件

<template>// 第2步:定义子组件引用父组件方法名<child @getUserName="handle"/>
</template><script setup>import Child from './components/child.vue';// 第1步:定义父组件需要被调用的方法const handle = (userId) => {console.log('子组件调用了父组件的方法',userId)}
</script>

 1.2.子组件[defineEmits]

<template><view>子组件</view><button @click="handleBtn">调用父组件的方法</button>
</template><script setup>//第1步:定义子组件调用父组件方法的引用const emit = defineEmits(['getUserName'])const handleBtn= () => {// 第2步:通过方法引用调用父组件方法emit('getUserName',12)}
</script>

 2.参数传递

2.1.单向传递[defineProps]

所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。

另外,每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。

prop 被用于传入初始值;而子组件想在之后将其作为一个局部数据属性。在这种情况下,最好是新定义一个局部数据属性,从 props 上获取初始值即可:

javascript">const props = defineProps(['initialCounter'])// 计数器只是将 props.initialCounter 作为初始值
// 像下面这样做就使 prop 和后续更新无关了
const counter = ref(props.initialCounter)
 2.1.1.父组件
<template><!--第2步:将需要传递的参数绑定到子组件--><child :userVO='userVO'/>
</template><script setup>import Child from './components/child.vue';// 第1步:定义需要传递到子组件的参数const userVO = ref({id: 18,name:'mark'})
</script>
  2.1.2.子组件
<template><view>子组件</view><!--第2步:使用父组件传递的数据--><span>{{caseVO.name}}</span>
</template><script setup>//第1步:定义需要接收父组件传递的数据const props = defineProps({caseVO:{type:Object,default:null}})//第2步:使用父组件传递的数据console.log('可以直接使用父组件传递的数据',props.caseVO.name)
</script>

2.1.双向绑定[defineModel、defineProps+defineEmits]

2.1.1 defineModel(vue3.4+)

defineModel 是一个便利宏。编译器将其展开为以下内容:

  • 一个名为 modelValue 的 prop,本地 ref 的值与其同步;
  • 一个名为 update:modelValue 的事件,当本地 ref 的值发生变更时触发。
 2.1.1.1 父组件
<template><!--第2步:将需要传递的参数绑定到子组件--><child v-model:userVO='userVO'/>
</template><script setup>import Child from './components/child.vue';// 第1步:定义需要传递到子组件的参数const userVO = ref({id: 18,name:'mark'})
</script>
 2.1.1.2 子组件 
<template><view>子组件</view><!--第2步:使用父组件传递的数据--><input v-model='caseVO.name'></input>
</template><script setup>//第1步:定义需要接收父组件传递的数据const caseVO= defineModel('caseVO')
</script>
2.1.2 defineProps+defineEmits(vue3.4-)
 2.1.2.1 父组件 
<template><!--第2步:将需要传递的参数绑定到子组件--><child v-model:userVO='userVO'/>
</template><script setup>import Child from './components/child.vue';// 第1步:定义需要传递到子组件的参数const userVO = ref({id: 18,name:'mark'})
</script>
 2.1.2.2 子组件 
<template><view>子组件</view><!--第3步:使用父组件传递的数据--><input v-model='caseVO.name' @input="updateFatherValue"></input>
</template><script setup>//第1步:定义需要接收父组件传递的数据const props = defineProps({caseVO: {type: Object}})//第2步:定义需要更新父组件传递的数据const emits = defineEmits(['update:caseVO'])const caseVO = ref(props.caseVO)//第4步:手动更新父组件对应的参数值const updateFatherValue = () =>{emits('update:caseVO',caseVO.value)}
</script>

 


http://www.ppmy.cn/server/13225.html

相关文章

金融时报:波场亮相哈佛大学并举办TRON Builder Tour活动

近日,波场TRON作为顶级白金赞助商出席哈佛区块链会议并成功举办TRON Builder Tour哈佛站活动,引发海外媒体热议。美联社、金融时报、Cointelegraph等国际主流媒体及加密知名媒体均对此给予了高度评价,认为本次大会对TRON Builder Tour活动具有里程碑意义,彰显了波场TRON致力于促…

蓝桥杯2024年第十五届省赛真题-拔河

审题可能会遇到的问题&#xff1a;认为所有人都必须参与拔河&#xff0c;但其实不用&#xff0c;只要符合l1<r1<l2<r2就行&#xff0c;不一定要全部人上场&#xff0c;比如只上场a1和a2他们的力量差是1其实也可以。 正解思路&#xff1a;前缀和枚举二分。枚举左区间&…

墨子web3时事周报

蚂蚁集团Web3研发进展与布局 国内Web3赛道的领军企业——蚂蚁集团&#xff0c;凭借其在前沿科技领域的深耕不辍&#xff0c;已在Web3技术研发疆域缔造了卓越战绩。特别是在引领行业革新的关键时刻&#xff0c;集团于今年四月末震撼推出了颠覆性的Web3全套解决方案&#xff0c…

广州大学《虚拟现实与游戏开发》实验报告一HTC-VR环境搭建与开发

广州大学学生实验报告 开课实验室&#xff1a; 学院 年级、专业、班 姓名 学号 实验课程名称 虚拟现实与游戏开发 成绩 实验项目名称 1. HTC-VR环境搭建与开发 指导老师 实验目的 HTC VIVE硬件安装虚拟现实开发环境搭建 3.熟悉虚拟现实硬件系统和…

【HTML】页面引用Vue3和Element-Plus

在现代前端开发中&#xff0c;Vue 3 和 Element Plus 是非常受欢迎的技术。Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架&#xff0c;而 Element Plus 是一个基于 Vue 3 的组件库&#xff0c;提供了丰富的 UI 组件&#xff0c;帮助开发者快速构建高质量的前端应用。 …

C++11统一列表初始化,initializer_list

目录 1.C11统一了列表的初始化 2.initializer_list 3.initializer_list是如何支持的 1.C11统一了列表的初始化 现在无论内置类型和自定义类型都可以用列表初始化。 class Date {public:Date(int year, int month, int day):_year(year),_month(month),_day(day) {}private:…

vue element ui 打开弹窗出现黑框问题

文章目录 问题描述解决方案 问题描述 大家好&#xff01;今天是2024年4月20日 | 农历三月十二&#xff0c;周六的我又做在公司里面写起了代码 今天在做项目的时候遇到一个奇怪的问题&#xff0c;如下图所示&#xff1a; 因为这个页面我做了两个弹框&#xff0c;先弹出来第一个弹…

ArcGIS无法链接在线地图或错误: 代理服务器从远程服务器收到了错误地址(验证服务器是否正在运行)。

这几天我们分享了&#xff01; 谷歌卫星影像图归来&#xff01;ArcGIS直连&#xff01;快来获取_谷歌影像lyr-CSDN博客文章浏览阅读666次&#xff0c;点赞11次&#xff0c;收藏9次。大概。_谷歌影像lyrhttps://blog.csdn.net/kinghxj/article/details/137521877一套图源搞定&a…