Vue 中 props 传递数据的坑

场景:父页面写了一个用户信息的表格,表格中每一行用户数据对应一个重置密码按钮,点击按钮会弹出对话框。重置密码需要传递用户 id 。

代码如下:

javascript 复制代码
<a-table>
   <template #bodyCell="{ column, record }">
     <template v-else-if="column.key === 'action'">
       <div class="editable-row-operations">
           <a-typography-link type="link" @click="handleResetPasswordModal()">
              重置密码
           </a-typography-link>
          </div>
       <ResetPasswordModal
         ref="resetPasswordModalRef"
         :id="record.id"
         :onSuccess="
           async () => {
             await fetchData()
           }"/>
     </template>
  </template>
</a-table>

子组件定义了 ref ,并且全部都是 resetPasswordModalRef 的同一个组件实例,由于表格中的每一行数据都是循环出来的,在循环中渲染组件时,所有实例共享同一个 ref,导致总是操作最后一个实例。所以传递 id 的时候,总是会传递循环中的最后一个 id 过去,导致子组件总是接收不到对应的 id。

解决方案:

1. 动态设置 ref

  1. 使用 ref 数组,动态设置 ref,避免所有实例共享一个 ref
html 复制代码
<template>
  <a-table :data-source="data">
    <a-column>
      <template #default="text, record, index">
        {{ record.id }}
        <ResetPasswordModal
          :ref="(el) => setModalRef(el, index)"  <!-- 动态设置ref -->
          :id="record.id"
          :onSuccess="fetchData"
        />
        <a-button @click="handleReset(record, index)">重置密码</a-button>
      </template>
    </a-column>
  </a-table>
</template>
javascript 复制代码
<script setup lang="ts">
import { ref } from 'vue'

const modalRefs = ref<any[]>([])  // 存储所有模态框的ref

const setModalRef = (el: any, index: number) => {
  if (el) {
    modalRefs.value[index] = el
  }
}

const handleReset = (record: any, index: number) => {
  console.log('操作记录:', record.id)
  modalRefs.value[index]?.openModal()
}
</script>

2. 单个模态框 + 动态数据(最推荐)

  • 父页面
javascript 复制代码
<template>
  <a-table :data-source="data">
    <a-column>
      <template #default="text, record">
        {{ record.id }}
        <a-button @click="handleReset(record)">重置密码</a-button>
      </template>
    </a-column>
  </a-table>

  <!-- 单个模态框在循环外部 -->
  <ResetPasswordModal
    ref="resetPasswordModalRef"
    :id="currentRecordId"
    :onSuccess="fetchData"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const resetPasswordModalRef = ref()
const currentRecordId = ref('')

const handleReset = (record: any) => {
  console.log('设置当前记录ID:', record.id)
  currentRecordId.value = record.id
  resetPasswordModalRef.value?.openModal()
}
</script>
  • 子组件

通过 props 接收,略

3. 使用方法传递参数

  • 父页面
javascript 复制代码
<template>
  <a-table :data-source="data">
    <a-column>
      <template #default="text, record">
        {{ record.id }}
        <a-button @click="handleReset(record.id)">重置密码</a-button>
      </template>
    </a-column>
  </a-table>

  <!-- 不传id,完全通过方法参数 -->
  <ResetPasswordModal
    ref="resetPasswordModalRef"
    :onSuccess="fetchData"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const resetPasswordModalRef = ref()

const handleReset = (id: string) => {
  console.log('传递ID:', id)
  resetPasswordModalRef.value?.openModal(id)
}
</script>
  • 子组件

定义一个响应式数据接收 id,略

相关推荐
程序员黑豆6 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC7 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea7 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
浮生望7 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少8 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0078 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis9 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝9 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
计算机魔术师10 小时前
新兴多智能体系统的模式与问题
前端
用户0595401744611 小时前
AI Agent 上下文污染踩坑实录:用 pytest + Redis 揪出 3 类记忆串号 bug,排查 6 小时
前端·css