现有一个需求如下

 

点击“存包记录”,出现弹窗(如下图) ,通过上图传过来的参数:订单id ,查询出来弹窗中的列表, 列表数据来自另一张表,与上图数据的表 关联)

 

 该需求实现一个主从详情视图。点击父列表中的一个“存包记录”按钮。出现一个模态弹窗。弹窗中的列表显示与所点击行相关的记录。该相关列表的数据来自一个与父列表不同的数据库表。这两个表由一个主键/外键关系(orderId)连接。 

技术思路梳理

Vue 父子组件通信的经典“自上而下传递 Props,自下而上触发 Events”模式中的前半部分。

第1步:父组件 - 触发与状态管理

  1. 触发事件:在父组件的表格中,点击“存包记录”按钮,通过 @click="storeRecords(scope.row)" 将当前行的整个数据对象 row 传递给 storeRecords 方法。
  2. 准备数据:在 storeRecords 方法中,从 row 对象中解构出关键的 orderId (this.orderId = row.orderId),并将其赋值给父组件 data 中的变量 orderId
  3. 展示子组件:通过设置 this.storeRecordOpen = true 打开弹窗,弹窗内渲染的是子组件 <LockerRecord>

第2步:父组件 -> 子组件 - 数据传递(Props)

这是最关键的桥梁。

<!-- 父组件 -->
<el-dialog>
  <!-- 将父组件 data 中的 orderId,作为名为 "orderId" 的 prop 传递给子组件 -->
  <LockerRecord :orderId="orderId"></LockerRecord> 
</el-dialog>
  • :orderId="orderId" 的含义是:将父组件的 orderId 变量,绑定到子组件的 orderId prop上。这是一个动态绑定,当父组件的 orderId 变化时,子组件会接收到新的值。

第3步:子组件 - 接收与响应(Props + Watch)

这是你方案中最精彩的部分,完美地解决了数据异步更新的问题。

  1. 声明接收:在子组件 LockerRecord.vue 中,通过 props: ['orderId'] 声明:“我期望接收一个名为 orderId 的数据”。
  2. 监听变化并响应:
    • 为什么需要 watch?因为子组件创建时,orderId 这个 prop 可能还没有从父组件传递过来(或者传递的是初始空值)。直接在 created() 钩子里调用 getList() 可能会拿错参数。
    • watch 就像一个哨兵,专门监视 orderId 这个 prop。
    • immediate: true:这是点睛之笔。它告诉 watch:“在创建好监视任务后,立即执行一次 handler”。这确保了即使 orderId 在组件创建后很快就有了值,也能被立刻捕获并执行查询。
    • handler(newVal, oldVal):当 orderId 发生变化时,这个函数被调用。newVal 就是从父组件传来的最新的 orderId
    • this.newOrderId = newVal; this.getList():你将新值赋给一个内部变量 newOrderId,然后调用 getList() 进行数据查询。这个流程非常稳健。

第4步:子组件 -> 后端 -> 子组件 - 数据查询与渲染

  1. 发起请求:子组件的 getList() 方法调用 API 函数 getRecord(this.newOrderId),将监听到的新 orderId 发送给后端。
  2. 后端处理:后端接收到 orderId,作为 @PathVariable 查询关联表,并返回对应的存包记录列表。
  3. 前端渲染:子组件接收到后端返回的数据,更新 list 和 total<el-table> 自动根据 list 的数据完成渲染。

总结:核心任务是创建一个父子组件间的交互,其中一个组件(父组件)持有一个按钮列表,点击这些按钮会打开一个弹窗(子组件),其中包含一个需要基于来自父组件的ID来获取数据的表格。