Vue中表格操作按钮通过emit抛出事件实现父子通信:子组件用this.$emit(Vue2)或defineEmits(Vue3)触发edit/delete事件,父组件用@监听并处理,推荐kebab-case事件名和结构化传参。

在 Vue 中,表格组件内的操作按钮点击后通过 emit 抛出事件,是父子组件通信最常用且推荐的方式。核心思路是:子组件(表格)内部按钮触发时调用 this.$emit()(Vue 2)或 emit()(Vue 3 组合式 API),父组件监听对应事件并处理业务逻辑。
Vue 2 写法:子组件 emit + 父组件 v-on 监听
子组件(如 TableList.vue)中,操作按钮绑定 click,调用 $emit 并传参:
<template>
<table>
<tr v-for="item in list" :key="item.id">
<td>{{ item.name }}</td>
<td>
<button @click="handleEdit(item)">编辑</button>
<button @click="handleDelete(item.id)">删除</button>
</td>
</tr>
</table>
</template>
<script>
export default {
props: ['list'],
methods: {
handleEdit(row) {
this.$emit('edit', row) // 抛出 'edit' 事件,携带整行数据
},
handleDelete(id) {
this.$emit('delete', id) // 抛出 'delete' 事件,只传 ID
}
}
}
</script>
父组件使用时,用 v-on(简写 @)监听:
<TableList :list="tableData" @edit="onEdit" @delete="onDelete" />
并在 methods 中定义处理函数:
立即学习“前端免费学习笔记(深入)”;
-
onEdit(row):接收子组件传来的 row,可打开弹窗、跳转路由等 -
onDelete(id):根据 ID 发起删除请求或确认提示
Vue 3(选项式 API)写法:保持兼容性
与 Vue 2 基本一致,只需确保组件配置中声明 emits 选项(非必须但推荐):
export default {
props: ['list'],
emits: ['edit', 'delete'], // 显式声明触发的事件
methods: {
handleEdit(row) {
this.$emit('edit', row)
}
}
}
Vue 3(组合式 API)写法:使用 defineEmits
在 <script setup> 中,需显式调用 defineEmits 获取 emit 函数:
<script setup>
import { defineEmits } from 'vue'
const props = defineProps(['list'])
const emit = defineEmits(['edit', 'delete']) // 声明并获取 emit 方法
const handleEdit = (row) => {
emit('edit', row) // 注意:这里不是 this.$emit
}
const handleDelete = (id) => {
emit('delete', id)
}
</script>
父组件监听方式完全相同:@edit="onEdit",无需改动。
注意事项和建议
- 事件名推荐用 kebab-case(如
row-click),避免和原生事件冲突,也更易读 - 传递参数建议结构化,例如
emit('edit', { row, index }),方便后续扩展 - 避免在表格内直接调用父组件方法(如
props.onEdit),违背单向数据流原则;统一走 emit 更清晰、解耦更强 - 如果操作需要异步反馈(如删除后刷新列表),由父组件负责执行并更新
list,子组件保持只读


















