参考:
ElementUI多个子组件表单的校验管理:https://www.jianshu.com/p/541d8b18cf95
Vue 子组件调用父组件方法总结:https://juejin.im/post/5c1370365188250f73759a79
Vue表单类的父子组件数据传递:https://juejin.im/entry/5ae32bc75188256717760b13
Vue官方文档:https://cn.vuejs.org/v2/guide/components-custom-events.html#%E4%BA%8B%E4%BB%B6%E5%90%8D
Vee-validate 父组件获取子组件表单校验结果:https://www.jianshu.com/p/cebbb08356e8
vue.js 父组件如何触发子组件的方法:https://www.cnblogs.com/mophy/p/8590291.html
当一个组件中表单过多时,需要将form表单抽取到一个单独的组件中,再从父组件中引用
其中,需要在父组件中对子组件中的表单进行校验,这其中涉及到父子组件的数据传递,以及父子组件之间的方法相互调用
在表单校验方面,我主要在子组件中写好校验表单的方法,在父组件中对子组件的校验方法进行调用
由于form表单中的数据需要双向绑定,即对 props 内的属性进行双向绑定时,就需要用到 .sync
修饰符,参考文档:https://cn.vuejs.org/v2/guide/components-custom-events.html#事件名
父组件:
dialog弹窗部分:
<el-dialog v-dialogDrag :close-on-click-modal="false" width="500px" title="新增生产基地信息" :visible.sync="dialogFormAddNew" :lock-scroll="true" center @close="cleanAddNew" > <add-new ref="addnew" @fetchData="fetchProductBase" @close="closeAddNew" :addnewData.sync="fpojo" :isEdit="isEdit"></add-new> <div slot="footer" class="dialog-footer"> <el-button @click="closeAddNew">取 消</el-button> <el-button @close="closeAddNew" type="primary" @click="addData()">确 定</el-button> </div> </el-dialog>
<add-new ref="addnew" @fetchData="fetchProductBase" @close="closeAddNew" :addnewData.sync="fpojo" :isEdit="isEdit"></add-new>
绑定属性:
ref:表单名,表单验证时要用到,子组件form表单在父组件中的名字
isEdit:自定义属性,用于判断是否为编辑状态
addnewData.sync:form表单的属性
绑定事件:
fetchData:刷新数据
close:关闭窗口
方法:
//提交新增数据 addData(formName) { // 父组件调用子组件方法进行校验,并提交新增数据 this.$refs.addnew.validataForm(); },
子组件:
注意:在子组件中:<div></div>是必须要存在的
<div> <el-form :rules="rules" ref="addNewForm" label-width="100px" label-position="right" :model="spojo" center > .............................. </div>
export default { name: "add-new", props: { addnewData: { type: Object }, isEdit: { type: Boolean, default: false } }, data() { return { spojo: { .................... }, //新增提交的数据 rules: { //校验规则 baseName: [ //required: true为必填 { required: true, message: "基地名称不能为空", trigger: "blur" } ], baseArea: [ //required: true为必填 { required: true, message: "基地面积不能为空", trigger: "blur" } ], positionMessage: [ //required: true为必填 { required: true, message: "位置信息不能为空", trigger: "blur" } ] } }; },
methods:(表单验证)
methods: { // 子组件校验表单 validataForm() { this.$refs["addNewForm"].validate(valid => { if (valid) { //提交表单 console.log("addData"); console.log(this.spojo); productionAreaMockApi.add(this.spojo).then(response => { const resp = response.data; if (resp.flag) { // 新增成功,刷新列表数据 this.$emit("fetchData"); // this.dialogFormAddNew = false; //关闭窗口 this.$emit("close"); console.log(resp.flag) } else { // 失败,出现提示信息 this.$message({ message: resp.message, type: "warning" }); } }); } else { return false; } }); } }
父子组件之间的数据传递,可在编辑表单数据时使用,(如打开编辑,需要将当前行的数据显示在表单上,此时需要父子组件间的数据传递)
参考:https://juejin.im/entry/5ae32bc75188256717760b13
// 因为不能直接修改props里的属性,所以不能直接addnewData通过v-model进行绑定 // 在这里我们需要监听addnewData,当它发生变化时,立即将值赋给data中的spojo watch: { addnewData: { immediate: true, handler(val) { this.spojo = val; } } }, mounted() { // props是单向数据流,通过触发update事件绑定addnewData, // 将data里的spojo指向父组件通过addnewData绑定的那个对象 // 父组件在绑定addnewData的时候,需要加上.sync this.$emit("update:addnewData", this.spojo); },