当前位置: 首页 > news >正文

vue3 tab切换函数回调刷新跳转页面

需求背景

页面miTab引用了两个组件A和B, 以tab切换方式显示,在tab页面A提交表单保存成功后跳转到tab页面B,并且tab页面B自动刷新表格列表能显示刚才保存成功的数据

出现的问题

跳转成功了,但是列表没刷新,排查后发现是没有在跳转后调用 tab B 的数据获取函数

解决方案

在页面miTab调用tab B组件的 getData 方法,前提是用 B页面提供注入功能来让父组件能够访问子组件的方法。
主要还得是在父组件中把逻辑处理好

关键代码

  • miTab.vue
<template><div><el-tabs :model-value="activeName" @tab-click="handleClick"><el-tab-pane label="CAD-BOM" name="CAD-BOM"><CADBOMComponent @a-reuse-success="switchToaTab" /></el-tab-pane><el-tab-pane label="a" name="a" ><aComponent ref="aComponent"/></el-tab-pane></el-tabs></div>
</template><script>
import { ref } from 'vue';
import CADBOMComponent from './CADBOMComponent.vue'; // 导入 CAD-BOM 组件
import aComponent from './aComponent.vue'; // 导入 a 组件export default {name: 'part',components: {CADBOMComponent,aComponent},setup() {const activeName = ref('CAD-BOM');const aComponent = ref(null); // 用于引用 aComponent 实例const handleClick = (tab, event) => {activeName.value = tab.props.name;};const switchToaTab = () => {// 当收到子组件的 a-reuse-success 事件时,切换到 a tabactiveName.value = 'a';if (aComponent.value) {aComponent.value.getData(); // 直接调用 aComponent 的 getData 方法}};return {activeName,handleClick,switchToaTab,aComponent};}
};
</script>
  • aTab
    表格表单代码以及其他逻辑处理太多,此处省略一万字…

export default {name: 'aTab',setup(_,context) {}const emit = context.emit;const MBOMaddEdit = () => {const data = {partNo: MBOMForm.partNo,partRev: MBOMForm.partRev,name: MBOMForm.name,cName: MBOMForm.cName,material: MBOMForm.material,gauge: MBOMForm.gauge,massqty: MBOMForm.massqty,partType: MBOMForm.partType}addMBom(data).then(res => {if (res.code !== 500) {ElMessage.success('恭喜您,添加成功!')//通知父组件切换到 MBOM tabemit('mbom-reuse-success');} else {ElMessage.error(res.msg)}})}
  • bTab
<template><div class="part"><div class="common-query"><div class="common-query-demo"><span>零部件名称</span><el-input placeholder="请输入零部件名称" v-model="query.name"></el-input></div><div class="common-query-demo"><el-button icon="el-icon-search" @click="handleQuery">查询</el-button><el-button icon="el-icon-refresh" @click="resetQuery"style="margin-left: 20px !important;">重置</el-button></div></div><div class="line-body"><el-button type="primary" class="handle-btn" icon="el-icon-circle-plus-outline"@click="addEdit">新建</el-button><el-button type="primary" class="handle-btn" icon="el-icon-delete" @click="deleteBatch">批量删除</el-button><el-table :data="tableData" :max-height="tableHeight" @selection-change="handleSelectionChange" stripeborder><el-table-column type="selection" width="55" fixed></el-table-column><el-table-column type="index" label="序号" width="50"></el-table-column><el-table-column prop="name" label="名称" sortable min-width="100"></el-table-column><el-table-column prop="cName" label="中文名称" min-width="100"></el-table-column><el-table-column prop="partNo" label="数模号 " min-width="100"></el-table-column><el-table-column prop="partRev" label="版本号" min-width="100"></el-table-column><el-table-column prop="material" label="材料" min-width="100"></el-table-column><el-table-column prop="gauge" label="规格" min-width="100"></el-table-column><el-table-column prop="massqty" label="重量" min-width="100"></el-table-column><el-table-column prop="partType" label="数据类型" min-width="100"></el-table-column><el-table-column prop="status" label="状态" min-width="100"><template #default="scope">{{ scope.row.isLock == 0 ? '未锁定' : '已锁定' }}</template></el-table-column><el-table-column fixed="right" label="操作" width="400"><template #default="scope"><el-button type="primary" icon="el-icon-view" @click="showTree(scope.row)">树形结构</el-button><el-button type="primary" icon="el-icon-view" @click="MBOMMux(scope.row)">MBOM复用</el-button><!-- 下载 --><el-button type="primary" icon="el-icon-download" @click="download(scope.row)">下载文件</el-button><i class="el-icon-delete" @click="deletePart(scope.row)"></i></template></el-table-column></el-table><el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange":current-page="query.pageNum" :page-sizes="[10, 15, 20, 25, 30]" :page-size="query.pageSize"layout="total, sizes, prev, pager, next, jumper" :total="total"></el-pagination><el-dialog :title="title" v-model="drawer" width="600px"><el-form :model="partForm" :rules="rules" ref="partFormsss" label-width="120px" class="demo-partForm"><el-form-item label="数模号:" prop="partNo"><el-input v-model="partForm.partNo" clearable></el-input></el-form-item><el-form-item label="版本号:" prop="partRev"><el-input v-model="partForm.partRev" clearable></el-input></el-form-item><el-form-item label="名称:" prop="name"><el-input v-model="partForm.name" clearable></el-input></el-form-item><el-form-item label="上级节点:" v-if="partForm.parentName"><el-input v-model="partForm.parentName" disabled></el-input></el-form-item><el-form-item label="中文名称:" prop="cName"><el-input v-model="partForm.cName" clearable></el-input></el-form-item><el-form-item label="材料:" prop="material"><el-input v-model="partForm.material" clearable></el-input></el-form-item><el-form-item label="规格:" prop="gauge"><el-input v-model="partForm.gauge" clearable></el-input></el-form-item><el-form-item label="重量:" prop="massqty"><el-input v-model="partForm.massqty" clearable></el-input></el-form-item><el-form-item label="数据类型:" prop="partType"><el-input v-model="partForm.partType" clearable></el-input></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="cancelEdit">取 消</el-button><el-button type="primary" @click="saveEdit">确 定</el-button></span></template></el-dialog></div></div>
</template><script>
import { reactive, ref, toRefs, unref, onMounted, nextTick, onUnmounted } from 'vue'
import { add, remove, listByPage, listAll, downloadFile } from '@api/pdm/part'
import { addMBom, getMBomDdata } from '@api/pdm/mbom'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import axios from 'axios';export default {name: 'bTab',setup() {// 定义的变量const state = reactive({query: {pageNum: 1,pageSize: 10,name: ''},statusList: [],title: '',drawer: false,  // 新建对话框handleId: '',  // 编辑id// 表数据tableData: [],total: 0,selectList: [],multipleSelection: []})const router = useRouter()// 通过计算表格距离页面底部的距离来实现表格高自适应const tableHeight = ref(window.innerHeight - 342)const partForm = reactive({partNo: '',partRev: '',name: '',cName: '',material: '',gauge: '',massqty: '',partType: '',parentId: '',parentName: ''})const partFormsss = ref(null)const rules = {name: [{ required: true, message: "此处为必填项" }],partNo: [{ required: true, message: "此处为必填项" }],partRev: [{ required: true, message: "此处为必填项" }]}//零部件表格function getData() {getMBomDdata(state.query).then(res => {state.total = res.data.totalstate.tableData = res.data.list})}// 新建零部件const addEdit = () => {state.drawer = truepartForm.parentName = ''state.title = '添加零部件'partForm.parentId = ''partForm.partNo = ''partForm.partRev = ''partForm.name = ''partForm.cName = ''partForm.material = ''partForm.gauge = ''partForm.massqty = ''partForm.partType = ''}//展示零部件const showTree = (row) => {// state.title = '编辑零部件'// state.drawer = true// state.btnShow = true// state.handleId = row.id// partForm.partNo = row.partNo// partForm.partRev = row.partRev// partForm.name = row.name// partForm.cName = row.cName// partForm.material = row.cName// partForm.gauge = row.gauge// partForm.massqty = row.massqty// partForm.partType = row.partType// router.push({path: '/pdm/property?partId='+row.id})router.push({path: '/pdm/property',query: {id: row.id}})}//断点续传// const download = async (row) => {//     const fileName = '11.png'; // 文件名//     const chunkSize = 1024 * 1024; // 分块大小,例如1MB//     let startByte = localStorage.getItem(`${fileName}-downloaded`) || 0;//     const config = {//         responseType: 'blob',//         headers: {//             'Range': `bytes=${startByte}-${startByte + chunkSize - 1}`,//         },//     };//     try {//         const response = await axios.get('/mes/file/download', config);//         // 直接处理响应,不再依赖于状态码检查//         const url = window.URL.createObjectURL(new Blob([response]));//         const link = document.createElement('a');//         link.href = url;//         link.download = fileName;//         document.body.appendChild(link);//         link.click();//         document.body.removeChild(link);//         // 更新已下载的字节数//         startByte += chunkSize;//         if (startByte < response.size) {//             localStorage.setItem(`${fileName}-downloaded`, startByte);//         } else {//             localStorage.removeItem(`${fileName}-downloaded`);//         }//     } catch (error) {//         console.error('Download error:', error);//     }// };const download = async (row) => {try {const data = {id: row.id}downloadFile(data).then(response => {if (response.code && response.code == 500) {ElMessage.error(response.msg)} else {// 创建一个URL表示Blob对象// const url = window.URL.createObjectURL(new Blob([response]));const url = '/mes/pdm/cadDownloadPart?id=' + row.id;// let fileName = response.headers['Content-Disposition'].split('filename=')[1];// 创建隐藏的可下载链接const link = document.createElement('a');link.href = urllink.style.display = 'none';// 将链接添加到DOM中,然后模拟点击下载document.body.appendChild(link);link.click();// 清理工作,释放URL对象window.URL.revokeObjectURL(url);link.remove();}})} catch (error) {// console.error('下载失败:', error);// alert('文件不存在或下载过程中出现问题!');ElMessage.error('下载失败')}};// 新建/编辑零部件const saveEdit = async () => {const form = unref(partFormsss)if (!form) returntry {await form.validate()if (state.title == '添加零部件') {addSavePart()}if (state.title == '编辑零部件') {updateSavePart()}state.drawer = false} catch (error) {console.error(error)ElMessage.error('抱歉,您有必填项未填!')}}const addSavePart = () => {const data = {partNo: partForm.partNo,partRev: partForm.partRev,name: partForm.name,cName: partForm.cName,material: partForm.material,gauge: partForm.gauge,massqty: partForm.massqty,partType: partForm.partType,}add(data).then(res => {state.drawer = falseElMessage.success('恭喜您,添加成功!')getData()})}const updateSavePart = () => {const data = {id: state.handleId,partNo: partForm.partNo,partRev: partForm.partRev,name: partForm.name,cName: partForm.cName,material: partForm.material,gauge: partForm.gauge,massqty: partForm.massqty,partType: partForm.partType}update(data).then(res => {state.drawer = falsegetData()ElMessage.success('恭喜您,保存成功!')})}// 删除零部件const deletePart = (row) => {const ids = []ids.push(row.id)deleteProData(ids)}// 调用删除零部件接口const deleteProData = (data) => {remove(data).then(res => {getData(state.query)ElMessage.success('恭喜您,删除成功!')})}//批量删除零部件function deleteBatch() {const sels = state.multipleSelectionif (sels.length != 0) {// 获取所有选中行的id组成的字符串,以逗号分隔const strIds = sels.map((item) => item.id).join()// split() 方法用于把一个字符串分割成字符串数组。const ids = strIds.split(',')deleteProData(ids)// ElMessage.success('您刪除了' + ids + '!')} else {ElMessage.error('您当前未选中!')}}// 新建取消const cancelEdit = () => {state.drawer = falsesetTimeout(() => {const form = unref(partFormsss)form.resetFields()}, 100)}const statusFormat = (row) => {for (let i = 0; i < state.statusList.length; i++) {if (row == state.statusList[i].dictValue) {return state.statusList[i].dictLabel}}}// 批量删除选中function handleSelectionChange(val) {state.multipleSelection = val}function handleQuery() {queryEdit(state.query)}function resetQuery() {state.query.name = ''}// 查询function queryEdit(query) {getData(query)ElMessage.success('恭喜您,查询成功!')}// 分页页数function handleSizeChange(val) {state.query.pageSize = valqueryEdit(state.query)}function handleCurrentChange(val) {state.query.pageNum = valqueryEdit(state.query)}function getHeight() {tableHeight.value = window.innerHeight - 342}// 页面加载时调用函数onMounted(() => {// 注册监听器window.addEventListener('resize', getHeight)// 调用函数getHeight()getData()})onUnmounted(() => {// 注销监听器window.removeEventListener('resize', getHeight)})return {...toRefs(state),tableHeight,rules,partFormsss,partForm,cancelEdit,saveEdit,handleSelectionChange,handleQuery,resetQuery,handleSizeChange,handleCurrentChange,showTree,addEdit,deletePart,deleteBatch,statusFormat,download,getData}}
}
</script><style lang="scss">
.part {width: 100%;height: 100%;.line-body {height: calc(100% - 120px);margin-top: 20px;box-shadow: $box-shadow;background: #fff;padding: 20px;.handle-btn {min-height: 32px;height: 32px;padding: 0 10px;margin-right: 10px;}.el-table {margin-top: 20px;td:last-child {.cell {display: flex;justify-content: space-between;padding: 0 10px;}}.cell {padding: 0;.head-url {height: 36px;position: relative;.el-image {position: absolute;top: 0;right: 0;bottom: 0;left: 0;margin: auto;border-radius: 5px;}}.el-tag {height: 25px;line-height: 25px;padding: 0 7px;}}.el-icon-delete {cursor: pointer;color: #EB7A40;font-size: 22px;}.el-icon-delete:hover {opacity: 0.9;}}}
}
</style>

希望我的解决方案能帮助到遇到同样问题的同学,奥利给!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • tensorflow keras Model.fit returning: ValueError: Unrecognized data type
  • WordPress外贸建站案例
  • 基于JAVA+SpringBoot+Vue+uniApp的校园日常作品商品分享小程序
  • 航班管理系统【C语言版】单文件编写
  • MPNN消息传递神经网络
  • IDEA的断点调试(Debug)
  • Ajax是什么?如何在HTML5中使用Ajax?
  • 分享一个 .NET EF 6 扩展 Where 的方法
  • ES6 字符串的新增方法(二十)
  • P4-AI产品经理-九五小庞
  • 云原生系列 - Jenkins
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • 【JavaScript 算法】最长公共子序列:字符串问题的经典解法
  • [数据集][目标检测]导盲犬拐杖检测数据集VOC+YOLO格式4635张2类别
  • RK3568 V1.4.0 SDK,USB OTG端子不能被电脑识别出adb设备,解决
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • extjs4学习之配置
  • go append函数以及写入
  • Java多态
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • PHP那些事儿
  • Python_网络编程
  • Python十分钟制作属于你自己的个性logo
  • SpringBoot 实战 (三) | 配置文件详解
  • 百度小程序遇到的问题
  • 服务器从安装到部署全过程(二)
  • 给github项目添加CI badge
  • 那些年我们用过的显示性能指标
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 思维导图—你不知道的JavaScript中卷
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 找一份好的前端工作,起点很重要
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​secrets --- 生成管理密码的安全随机数​
  • ​虚拟化系列介绍(十)
  • #define与typedef区别
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (~_~)
  • (02)vite环境变量配置
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (4.10~4.16)
  • (安卓)跳转应用市场APP详情页的方式
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • .axf 转化 .bin文件 的方法
  • .describe() python_Python-Win32com-Excel
  • .gitignore文件—git忽略文件
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net 微服务 服务保护 自动重试 Polly
  • .NET 中使用 Mutex 进行跨越进程边界的同步