Vue3组件通信之二_defineExpose编译器宏函数

Vue3组件通信之二_defineExpose编译器宏函数

文章目录

  • Vue3组件通信之二_defineExpose编译器宏函数
  • 1. defineExpose
  • 2.简单理解
  • 3. 实战案例
    • 1. 父子组件之间通信
      • 1. 子组件中通过defineExpose暴露属性或方法
      • 2. 父组件中使用子组件暴露的方法
    • 2. 同级(兄弟)组件之间方法调用或传值
      • 1. 子组件1
      • 2. 子组件2
      • 2. 借助父组件实现子组件1与子组件2之间通信

1. defineExpose

官网文档:https://cn.vuejs.org/api/sfc-script-setup.html#defineexpose

使用 <script setup> 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。

可以通过 defineExpose 编译器宏来显式指定在 <script setup> 组件中要暴露出去的属性:

<script setup>
import { ref } from 'vue'const a = 1
const b = ref(2)defineExpose({a,b
})
</script>

当父组件通过模板引用的方式获取到当前组件的实例,获取到的实例会像这样 { a: number, b: number } (ref 会和在普通实例中一样被自动解包)

2.简单理解

  1. defineExpose使用在子组件中或兄弟组件之间的通讯
  2. 可以暴露属性或方法给父组件使用和调用

3. 实战案例

1. 父子组件之间通信

1. 子组件中通过defineExpose暴露属性或方法

  1. 子组件中定义,SysDictAddComponent.vue如下
<script setup lang="ts">
import { ref, defineExpose} from "vue";const addSubmit = () => {//...
}let msg = ref('hello,jinshengyuan')
//暴露属性和方法给其父组件使用
defineExpose({msg,addSubmit,updateFrom
})
</script>

2. 父组件中使用子组件暴露的方法

  1. 引入子组件时给给组件设置ref属性如 <SysDictAddComponent ref="sysDictAddComponent"></SysDictAddComponent>
  2. setup函数中定义ref对象,const sysDictAddComponent = ref()
  3. 通过sysDictAddComponent.value.属性sysDictAddComponent.value.方法名进行使用
  4. 具体使用如下面末尾部分
<template><a-drawertitle="新增用户":width="720":visible="visible":body-style="{ paddingBottom: '80px' }":footer-style="{ textAlign: 'right' }"@close="onClose"><!--新增用户form组件--><SysDictAddComponent ref="sysDictAddComponent"></SysDictAddComponent><!--按钮--><template #extra><a-space><a-button @click="onClose">关闭</a-button><a-button type="primary" @click="onSubmit">提交</a-button></a-space></template></a-drawer>
</template>
<script setup lang="ts">
import {ref, watch} from 'vue';
import SysDictAddComponent from "../../components/sys/SysDictAddComponent.vue";//接收父组件传递的对象
const props = defineProps<{subVisible: boolean
}>()
//抽屉是否显示函数
const visible = ref<boolean>(false);//监听子组件传递的subVisible值并给visible重新赋值
watch(() => (props.subVisible), (newVal, oldVal) => {console.log("new:" + newVal, "old:" + oldVal)visible.value = newVal
})//定义emit事件
const emit = defineEmits(['changeSubVisible','addSuccess'])const onClose = () => {visible.value = false;//通知父组件改属性emit('changeSubVisible', false)
};
//获取子组件暴露的对象
const sysDictAddComponent = ref()
//提交时校验
const onSubmit = () => {//visible.value = false;//调用SysUserAddComponent组件中通过defineExpose暴漏的addSubmit方法sysDictAddComponent.value.addSubmit()//
}
</script>

2. 同级(兄弟)组件之间方法调用或传值

注意:同级(兄弟)组件之间传值是借助父组件来完成的,

1. 子组件1

子组件1FormButton.vue

<template><el-button type="primary" @click="submit">提交</el-button><el-button @click="reset">重置</el-button><el-button @click="close">关闭</el-button>
</template>
<script setup lang="ts">
import {defineEmits, inject, ref} from 'vue'//调用父组件的方法,执行关闭操作
const emits = defineEmits(['doSubmit','doClose']);
const close = () => {emits('doClose')
}const submit = () => {emits('doSubmit')
}    //1.使用inject函数调用隔代组件中provide提供的函数
/*const doSubmitHandler = inject('doSubmit',()=>{},false)
const doRectHandler = inject('doReset',()=>{},false)
const submit = () => {//doSubmitHandler.call(null)//console.log(roleFormComponent.value.roleFormRef)
}
const reset = () => {//doRectHandler.call(null)//roleFormComponent.value.resetForm()
}*//*
2. 使用defineEmits函数调用父组件的方法
const emits = defineEmits(['doSubmit', 'doReset', 'doClose']);
const submit = () => {emits('doSubmit')
}
const reset = () => {emits('doReset')
}
const close = () => {emits('doClose')
}
2. 父组件中使用如下:
<FormButton @doSubmit="test" @doReset="rest" @doClose="close"></FormButton>
父组件中的三个方法如下:
const test = ()=>{console.log("我是父组件提交方法1")
}const rest = ()=>{console.log("我是父组件重置方法2")
}const close = ()=>{console.log("我是父组件关闭方法3")
}*/</script><style scoped lang="scss"></style>

2. 子组件2

子组件2RoleFormComponent.vue

<template><el-formref="roleFormRef":model="ruleForm":rules="rules"label-width="120px"class="demo-ruleForm":size="formSize"status-icon><el-form-item label="角色编码" prop="roleCode"><el-input v-model="ruleForm.roleCode"/></el-form-item><el-form-item><el-button type="primary" @click="submitForm(roleFormRef)">Create</el-button><el-button @click="resetForm(roleFormRef)">Reset</el-button></el-form-item></el-form>
</template><script setup lang="ts">
import {reactive, ref, defineExpose} from 'vue'
import type {FormInstance, FormRules} from 'element-plus'const formSize = ref<string>('default')
const roleFormRef = ref<FormInstance>()const submitForm = async (formEl: FormInstance | undefined) => {console.log('表单提交执行了。。。。')if (!formEl) returnawait formEl.validate((valid, fields) => {if (valid) {console.log('submit!', {...ruleForm})} else {console.log('error submit!', fields)}})
}
//暴露方法给父组件使用,然后同级(兄弟)组件借助父组件中某个子组件的ref进行方法调用
defineExpose({roleFormRef,submitForm
})
</script><style lang="scss" scoped></style>

2. 借助父组件实现子组件1与子组件2之间通信

  1. 子组件1与子组件2总各自通过defineExpose暴露属性或方法给父组件

  2. 然后借助父组件实现子组件1与子组件2之间通信

<template><el-drawer v-model="drawer" :direction="direction" :before-close="handleClose" size="50%"><template #header><h4>{{ formTitle }}</h4></template><template #default><!--子组件1: RoleFormComponent--><RoleFormComponent ref="roleFormComponent"></RoleFormComponent></template><template #footer><div style="flex: auto;align-content: center;align-items: center"><!--子组件2:FormButton--><FormButton @doSubmit="formButtSubmit" @doClose="handleClose"></FormButton></div></template></el-drawer>
</template><script setup lang="ts">
import {ref, defineProps, watch, provide} from 'vue'
import {ElMessageBox} from 'element-plus'
import RoleFormComponent from '@/components/sys/drawer/RoleFormComponent.vue'
import FormButton from "@/components/public/FormButton.vue"
//定义props,父组件向子组件传值
const props = defineProps<{showDrawer: boolean
}>();
//显示抽屉,默认false
const drawer = ref<boolean>(false)
const formTitle = ref<string>('角色新增')watch(() => (props.showDrawer), (newVal, oldVal) => {console.log(newVal, oldVal)drawer.value = newVal
})//定义emit事件,调用父组件的方法
const emit = defineEmits(['updateDrawerVisible'])//借助父组件进行同级组件传值及方法调用,如:FormButton组件调用RoleFormComponent组件中的formButtSubmit方法
const roleFormComponent = ref()
const formButtSubmit = ()=>{console.log(roleFormComponent.value.roleFormRef)//获取RoleFormComponent组件暴露的roleFormRef及调用submitForm方法roleFormComponent.value.submitForm(roleFormComponent.value.roleFormRef)
}</script><style lang="scss" scoped></style>

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

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

相关文章

【算法可视化】模拟算法专题

运行平台 Algorithm Visualizer 神奇的幻方 [NOIP2015 提高组] 神奇的幻方 // import visualization libraries { const { Tracer, Array2DTracer, Array1DTracer, LogTracer, Randomize, Layout, VerticalLayout } require(algorithm-visualizer); // } function filledA…

微前端之什么是微前端

什么是微前端 微前端分类 基于路由的微前端&#xff1a;组件化微前端&#xff1a;iframe嵌入式微前端&#xff1a; 优点缺点 动态加载/懒加载微前端&#xff1a;微应用容器化方案&#xff1a; 微前端解决方案 single-spa阿里巴巴 Cloud Alfaiframe 方案Web ComponentsModule Fe…

关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法

0. 接口结构&#xff1a;1. 方法报错&#xff1a;2. 解决方法&#xff1a;3. 原因分析&#xff1a; 0. 接口结构&#xff1a; 【接口】&#xff1a; public interface PurchaseOrderService extends IService<PurchaseOrder> {}【接口实现类】&#xff1a; public cla…

【Python】新手入门(5):# -*- coding: UTF-8 -*- 的作用详解

【Python】新手入门&#xff08;5&#xff09;&#xff1a;# -*- coding: UTF-8 -*- 的作用详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础…

spring ResponseBodyAdvice 失效 不起作用

## spring web ResponseBodyAdvice 当 请求 controller 的RequestMapping void 方法时&#xff0c; 如果方法参数包含HttpServletResponse参数就会失效。 解决方法&#xff1a; 一、去掉HttpServletResponse参数 二、把void 改成对象&#xff0c;然后使用return 手动返回值。

ssm基于javaEE+springboot校园闲置二手物品拍卖交易平台_ngad7

为提升浏览用户观感及使用体验&#xff0c;本系统要具有易用性和美观性。通过页面的简单提示就可完成操作&#xff0c;校园闲置物品交易平台展示界面应该清楚简洁&#xff0c;使用户通过美观的前台页面能快速定位想要浏览的校园闲置物品交易平台信息。后台界面也应简约&#xf…

Servlet: 噩梦开始的地方

在Web开发的世界里&#xff0c;Servlet技术占据了历史的长河。它是Java EE规范的一部分&#xff0c;为Web应用提供了动态生成Web内容的方法。尽管Servlet为Java Web开发奠定了基石&#xff0c;随着技术的演进和新需求的出现&#xff0c;开发者们逐渐发现&#xff0c;与现代Web开…

java岗位面试题总结,关于网络优化你必须要知道的重点

前言 最近有很多朋友向我求教经验&#xff0c;因为我自己工作相对于稳定&#xff0c;在这里给大家分享一个粉丝朋友的经历&#xff0c;他作为一个曾经的菜鸡面试者&#xff0c;在不断的失败中成长&#xff0c;最终斩获了多份offer&#xff0c;因此特别想在此分享一下他的面试成…

【C++精简版回顾】20.模板的使用

1.模板起源 1.模板的定义 1.针对函数属性模板 //针对函数属性 template <class VOID > VOID print1(int a) {cout << a << endl; } 2.针对数据属性模板 //针对数据属性 template <typename INT,typename FLOAT> void print2(INT a,FLOAT b) {cout <…

从零学习Linux操作系统 第三十部分 部署Anisble

一、ansible实验环境的部署 主控机 更改服务器主机名 hostnamectl set-hostname westos_ansible.westos.org 主服务器需要能够实现上网 修改网卡使之能够上网 能ping通 代表可以连接外网 搭载本地软件仓库 并且挂载镜像 装载 dnf install httpd -y 让其开机启动并且…

【C#面向对象设计模式】02. Singleton单件(创建型模式)

【C#面向对象设计模式】02. Singleton单件&#xff08;创建型模式&#xff09; 0. 模式分类 从目的来看&#xff1a; 创建型模式&#xff1a;负责对象创建。结构型模式&#xff1a;处理类与对象间的组合。行为型模式&#xff1a;类与对象交互中的职责分配。 从范围来看&#…

.kat6.l6st6r勒索病毒的最新威胁:如何恢复您的数据?

导言&#xff1a; 在当今数字化时代&#xff0c;数据安全变得至关重要。然而&#xff0c;随着网络威胁不断增加&#xff0c;勒索病毒已成为企业和个人面临的严重威胁之一。其中&#xff0c;.kat6.l6st6r勒索病毒是最新的变种之一&#xff0c;它能够加密您的数据文件&#xff0…

解密程序员的“藏宝图”:我的祖传代码大公开

程序员是如何看待“祖传代码”的&#xff1f; 大家好&#xff0c;我是小明&#xff0c;一位充满好奇心和分享热情的程序员。今天&#xff0c;我要为大家揭开我心中的“藏宝图”——那些我认为值得传世的祖传代码。让我们一同踏上这场奇妙的代码冒险之旅吧&#xff01; 宝物一…

极简sklearn上手教程,快速体验特性

文章目录 极简sklearn上手教程&#xff0c;快速体验特性1. **环境搭建与安装**2. **用户指南&#xff1a;监督学习模块 - 线性模型**3. **模型评估与选择 - 超参数调优**4. **数据预处理与转换 - 标准化**5. **统计检验与依赖分析 - 部分依赖图**6. **大规模计算与性能优化 - 并…

ros2 launch如何控制node的启动顺序

ros2 launch如何控制node的启动顺序 文章目录 引言如何写launch文件启动流程图具体launch代码总结引言 本文用来说明如何控制ros2 launch 节点的先后顺序,我们有时候需要一个节点启动完成后再启动其它节点,实现这个功能有两种方式: 在launch.py时写event根据事件触发使用li…

DSP TMS320F28374S配置CAN通讯(个人使用总结笔记)

使用的CANB 大致流程 1.初始化GPIO 2.CANInit(can_base); 3.CANClkSourceSelect(can_base, 0); 4.CANIntEnable(can_base, CAN_INT_IE0 | CAN_INT_STATUS); 5.PieCtrlRegs.PIEIER9.bit.INTx7 1;//使能第1组中断的第7个小中断&#xff0c;即CANB_0 6.CANEnable(can_base…

vue-路由跳转和路由传参!!!

需求&#xff1a;在修改商品时&#xff0c;会进行页面跳转&#xff0c;通过点击修改按钮进行页面跳转。这时我们需要将商品的id携带过去 一、首先我们在查询页面实现路由跳转并携带参数。 1.1、修改按钮 <el-button type"primary" size"small" click&qu…

体验Node.js的安装和运行

Node.js概述 Node.js是一个基于Chrome V8引擎的JavaScript运行环境。它允许JavaScript代码在服务器端运行&#xff0c;使得开发人员可以使用同一种语言编写前端和后端的代码。Node.js使用事件驱动、非阻塞I/O模型&#xff0c;使其轻量且高效&#xff0c;非常适合数据密集型的实…

mpi4py的安装

一. MPI的安装 1. 下载MPI 安装包 到官网&#xff1a;http://www.mpich.org/downloads/ 下载mpi-3.2.1版本的MPI 包。 2. 解压安装包 到下载安装包的目录下&#xff0c;可以看到有mpi-3.2.1.tar.gz的压缩包&#xff0c;在终端运行如下命令&#xff1a; tar -zxvf mpich-3.…

Leetcode : 506. 相对名次

思路 &#xff1a; 遍历计算每个元素比它大的元素个数&#xff0c;并判断做出对应结果标签&#xff1b; #include <iostream> #include <vector>using namespace std;class Solution { public:vector<string> findRelativeRanks(vector<int>& scor…