Vue组件传参报错:type属性自定义验证失败排查
报错原因与解决方法
报错原因
引用传递导致原对象被意外修改
你传递给模态框的是原表单中input对象的引用,而非独立副本。当在模态框里编辑type属性时,实际上直接修改了原页面中正在使用的input对象的type值。而原页面的<b-form-input>组件对type属性有严格的内置验证(仅支持合法的HTML输入类型,如text/number/email等),当type被改成select这类不支持的值时,就会触发Invalid prop: custom validator check failed for prop "type"错误。表单组件的渲染逻辑不匹配
模态框传递给c-form的form结构是{inputs: {input}},但c-form默认的渲染逻辑是基于data.container的,这部分在模态框模式下不会生效。你缺少针对editInput模式的专属编辑UI,导致编辑操作的对象混乱。
解决方法
1. 深拷贝对象,切断引用
打开模态框时,对要编辑的input对象进行深拷贝,避免修改原对象。修改Form.vue中的openModalEditForm方法:
openModalEditForm(input){ // 使用JSON序列化实现深拷贝(适合无特殊类型的对象) const clonedInput = JSON.parse(JSON.stringify(input)); this.modal = { inputs: { input: clonedInput, } }; setTimeout(() => { this.$bvModal.show('modal-edit-form') }, 100); }
如果你的input对象包含函数、Symbol等JSON无法序列化的内容,建议使用lodash.cloneDeep替代。
2. 为c-form添加editInput模式的专属UI
在c-form的模板中,区分普通渲染模式和编辑模式,添加编辑input配置的界面:
<template> <!-- 普通模式:渲染表单输入 --> <div v-if="data.container && !editInput"> <!-- 保留你原来的b-card、row等渲染代码 --> </div> <!-- 编辑模式:修改input的配置项 --> <div v-if="editInput"> <b-form-group label="Tipo de Campo"> <b-form-select v-model="data.inputs.input.type" :options="typeOptions"></b-form-select> </b-form-group> <b-form-group label="Rótulo"> <b-form-input v-model="data.inputs.input.label"></b-form-input> </b-form-group> <b-form-group label="Tamanho"> <b-form-select v-model="data.inputs.input.size" :options="sizeOptions"></b-form-select> </b-form-group> <!-- 根据需要添加placeholder、required等其他配置的编辑控件 --> </div> </template>
3. 实现保存逻辑,同步修改到原对象
在模态框组件中添加保存事件,将修改后的对象传递给父组件,再同步到原表单:
- 修改
c-modalEditForm.vue的script部分:
export default { // ...其他配置 methods: { save() { this.$emit('save-edit', this.form.inputs.input); this.$bvModal.hide('modal-edit-form'); } } }
- 在
Form.vue中监听保存事件并处理更新:
<c-modal-edit-form :form="modal" v-if="modal" @save-edit="handleSaveEdit" />
添加handleSaveEdit方法:
methods: { // ...其他方法 handleSaveEdit(updatedInput) { // 遍历原表单结构,找到对应的input对象并更新属性 const updateInput = (container) => { for (const row of container) { for (let i = 0; i < row.length; i++) { // 这里可以根据唯一标识匹配,比如name+label,或者给input添加id属性 if (row[i].name === updatedInput.name && row[i].label === updatedInput.label) { Object.assign(row[i], updatedInput); return true; } } } return false; }; // 遍历所有card容器查找目标input for (const card of this.form.container) { if (updateInput(card)) break; } this.modal = null; } }
内容的提问来源于stack exchange,提问作者Gabriel Edu
相关产品推荐
相关产品推荐

