Vue.js中Delete按钮点击意外触发Save方法的异常求助
问题:Vue模态框中点击Delete按钮意外触发Save方法及函数不存在报错
在Vue.js项目的EditInstruction模态框里有两个按钮:Delete Instruction(绑定deleteInstruction方法)和Save Instruction(绑定saveEditInstruction方法)。点击Delete按钮时,控制台先输出deleteInstruction的执行日志,随后会意外触发saveEditInstruction方法。尝试过重命名方法、调整方法顺序、禁用Save按钮、清除浏览器缓存等操作,问题依旧;将save方法重命名为saveEditInstruction后,还出现_ctx.saveEditInstruction is not a function的报错。
相关代码及日志
1. EditInstruction模态框按钮代码
<!-- SUBMIT/ delete BUTTONS --> <div class="flex items-center gap-8"> <button class="btn-warning mt-4" @click="this.deleteInstruction(editInstruction)">Delete Instruction</button> <button type="submit" class="btn-primary mt-4" @click='saveEditInstruction'>Save Instruction</button> </div>
2. deleteInstruction方法代码
deleteInstruction(_instruction){ console.log('deleteInstruction _instruction.id = %s', _instruction.id) this.swalCustom(`Delete ${_instruction.requestpath}?`, `Are you sure you want to delete ${_instruction.requestpath}?`, 'warning', true, true, 'I am sure.', 'Cancel') .then(results=>{ if(results.isConfirmed){ this.swalLoading('Deleting...') _url = 'http://localhost:8000/api/instructions/' + _instruction.id + '/' console.log( '_url = %s ', _url) setTimeout(()=>{ getAPI.delete(_url) .then(res=>{ this.swalSuccess('Deleted') }) .catch(err=>{ this.swalError('Error in deleting ') }) this.loadInstructions() this.toggleModal('editInstructionModal') }, 1000) } }) },
3. saveEditInstruction方法代码
saveEditInstruction(row){ console.log('saveEditInstruction()') this.swalLoading('Updating Instruction...') //check for completeness if(true){ console.log('saveEditInstruction row.id = %s', row.id) setTimeout(()=>{ // POST API FOR ADDING Instruction getAPI.put('http://localhost:8000/api/instructions/' + row.id + '/', row) .then(res=>{ // SETS MESSAGE FOR RESPONSE let message = `Instruction ${row.requestpath} ${row.description} has been successfully added.` // DISPLAYS SUCCESS SCREEN/MODAL this.swalSuccess(message) this.loadInstructions() this.toggleModal('editInstructionModal') }) .catch(err=>{ this.swalError(err) }) }, 1000) this.loadInstructions() this.toggleModal('editInstructionModal') } },
4. 控制台日志(初始问题)
deleteInstruction _instruction.id = 1 InstructionsTableModal.vue:438 saveEditInstruction() InstructionsTableModal.vue:442 saveEditInstruction row.id = 1 InstructionsTableModal.vue:330 loadInstructions() mixins.js:130
5. 重命名save方法后的报错日志
runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of native event handler at <BaseTransition appear=true persisted=false mode=undefined ... > at <Transition appear="" name="slide-fade" > at <BaseTransition appear=false persisted=false mode=undefined ... > at <Transition onClose=fn > at <Modal width="w-[38rem]" ref="editInstructionModal" onClose=fn > at <InstructionsTableModal core=true width="w-[48rem]" ref="InstructionsTableModal" ... > at <TableMx onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy(Object) {validate: ƒ, formatPrice: ƒ, formatPriceIntl: ƒ, formatDateTime: ƒ, …} > > at <RouterView> at <App> warn2 @ runtime-core.esm-bundler.js:38 logError @ runtime-core.esm-bundler.js:212 handleError @ runtime-core.esm-bundler.js:204 callWithErrorHandling @ runtime-core.esm-bundler.js:158 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:164 invoker @ runtime-dom.esm-bundler.js:339 runtime-core.esm-bundler.js:218 Uncaught TypeError: _ctx.saveEditInstruction is not a function at InstructionsTableModal.vue:160:36 at runtime-dom.esm-bundler.js:1450:16 at callWithErrorHandling (runtime-core.esm-bundler.js:155:22) at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:164:21) at HTMLFormElement.invoker (runtime-dom.esm-bundler.js:339:9) (anonymous) @ InstructionsTableModal.vue:160 (anonymous) @ runtime-dom.esm-bundler.js:1450 callWithErrorHandling @ runtime-core.esm-bundler.js:155 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:164 invoker @ runtime-dom.esm-bundler.js:339 tablemx:1 Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received
解决方案
1. 解决Delete按钮触发Save方法的问题
问题根源是Delete按钮触发了表单默认提交行为:Save按钮为type="submit",点击Delete按钮时,浏览器会默认触发表单submit事件,进而执行Save相关逻辑。
修复步骤:
- 给Delete按钮添加
type="button",明确它不是提交按钮; - Vue模板中调用方法无需加
this.,直接写方法名:
<button type="button" class="btn-warning mt-4" @click="deleteInstruction(editInstruction)">Delete Instruction</button>
2. 解决_ctx.saveEditInstruction is not a function报错
该报错通常由以下原因导致,对应修复方式:
- 方法定义位置错误:确认
saveEditInstruction是定义在组件的methods选项中,而非computed或外部代码块; - 拼写/缓存问题:检查方法名拼写(大小写一致),重启开发服务器避免缓存残留;
- 参数传递不匹配:模板中调用
saveEditInstruction未传参,但方法定义需要row参数,修改模板传递当前编辑对象:
<button type="submit" class="btn-primary mt-4" @click='saveEditInstruction(editInstruction)'>Save Instruction</button>
或者在方法内部直接使用组件的editInstruction数据,去掉参数:
saveEditInstruction(){ const row = this.editInstruction; // 后续逻辑保持不变 }
3. 额外优化建议
- 规范表单提交逻辑:使用
@submit.prevent阻止表单默认提交行为,统一处理保存逻辑:
<form @submit.prevent="saveEditInstruction(editInstruction)"> <!-- 表单内容 --> <div class="flex items-center gap-8"> <button type="button" class="btn-warning mt-4" @click="deleteInstruction(editInstruction)">Delete Instruction</button> <button type="submit" class="btn-primary mt-4">Save Instruction</button> </div> </form>
- 修正异步操作顺序:
saveEditInstruction中loadInstructions和toggleModal原本在setTimeout外部,会在API请求完成前执行,导致数据更新不及时,需移到then回调内部:
saveEditInstruction(row){ console.log('saveEditInstruction()') this.swalLoading('Updating Instruction...') if(true){ console.log('saveEditInstruction row.id = %s', row.id) setTimeout(()=>{ getAPI.put('http://localhost:8000/api/instructions/' + row.id + '/', row) .then(res=>{ let message = `Instruction ${row.requestpath} ${row.description} has been successfully updated.` this.swalSuccess(message) this.loadInstructions() this.toggleModal('editInstructionModal') }) .catch(err=>{ this.swalError(err) }) }, 1000) } },
内容的提问来源于stack exchange,提问作者Ali Vleotsky
相关产品推荐
相关产品推荐

