參考:
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); },