一个添加,编辑与一体的组件,如果你的自定义组件写的不多,那么这个参考就比较好了,
开始的绑定就不多说了,change那里是和 v-model 有一个默认的约定,它能控制组件的显示与隐藏,当然绑定visible也是可以的,值得注意的是如果要全局验证,在model中添加属性,rules来验证就可以,如果不好写,就好像下面的那样,那么就要动态来绑定prop的值,一般用索引来会比较好,[索引.name] 这样绑定,如果没有直接校验的,就用空数组来表示,表格的key一般指定,支持函数和字符串,字符串方便点,如果提交的时候没有判断提交数据是否为空,那么可以在计算属性那里判断,为空就不让提交
<template> <a-modal v-bind="$attrs" v-on="$listeners" :title="title" :visible="value" v-on:change="value=>$emit('input',value)" :confirm-loading="confirmLoading" :footer="null" destroy-on-close :width="817" @cancel="handleCancel" > <a-form-model ref="addTableTestForm" :model="dataTableTestList" :rules="rules"> <a-table class="test-table" :columns="columns" :data-source="dataTableTestList" :pagination="false" row-key="id" > <template slot="action" slot-scope="text,record"> <a href="javascript:;"> <a-button type="danger" size="small" shape="circle" @click="handleRemoveSku(record.id)"> <a-icon type="close"></a-icon> </a-button> </a> </template> <template slot="name" slot-scope="text,record,index"> <a-form-model-item :prop="`${index}.name`" :rules="{ required: true, message: 'name is not null', trigger: ['blur'] }" > <a-input v-model="record.name"></a-input> </a-form-model-item> </template> <template slot="age" slot-scope="text,record,index"> <a-form-model-item :prop="`${index}.age`" :rules="{ required: true, message: 'age is not null', trigger: ['blur'] }" > <a-input v-model="record.age"></a-input> </a-form-model-item> </template> </a-table> <div class="text-center u-m-t-20" v-if="confirmBtnText == 'Create'"> <a-button type="primary" @click="handleAddSKu"> <span>Add New Sku</span> </a-button> </div> <div class="text-right"> <a-button :loading="confirmLoading" type="primary" @click="handleConfirm" :disabled="testTableDisable"> <span>{{confirmBtnText}}</span> </a-button> </div> </a-form-model> </a-modal> </template> <script> import actionForm from "../mixins/actionForm"; const __columns = [ { dataIndex: 'name', key: 'name', title: 'Name', scopedSlots: {customRender: 'name'}, }, { dataIndex: 'age', key: 'age', title: 'Age', scopedSlots: {customRender: 'age'}, }, { key: 'action', title: 'Action', scopedSlots: {customRender: 'action'}, }, ] export default { name: "AddTestTable", props: { value: { type: Boolean, default: false }, confirmLoading: { type: Boolean, default: false }, dataTableTestModal: { type: Array, default: ()=>([]) }, title: { type: String, title: 'Add SKU' }, confirmBtnText: { type: String, default: 'Create' }, type: { type: String, default: 'Create' } }, mixins: [actionForm], components: {}, watch: { dataTableTestModal: { deep: true, immediate: true, handler(newVal) { if (newVal) { this.dataTableTestList = _.cloneDeep(newVal) console.log(newVal,'ddd') } } } }, filters: {}, computed: { testTableDisable() { let flag = false if (_.isEmpty(this.dataTableTestList)) { flag = true } return flag } }, data() { return { dataTableTestList: [ // { // id: $__utils__.uuid(), // name: '', // age: '' // } ], columns: __columns, rules: [] }; }, methods: { handleCancel() { this.$emit('input', false) this.$emit('hide') }, handleRemoveSku(itemId) { console.log(itemId) // 找到对应的索引,才能删除 const _self = this const _index_del = _self.dataTableTestList.findIndex( item => item.id === itemId ) if (_index_del > -1) { _self.dataTableTestList.splice(_index_del,1) } }, handleAddSKu() { console.log('handleAddSKu') const _self = this let newItem = { id: $__utils__.uuid(), name: '', age: '' } if (_self.dataTableTestList && _self.dataTableTestList.length) { _self.dataTableTestList.push(newItem) } else { // 如果你是第一次进入,那么就要更新为响应式 _self.$set(_self.dataTableTestList,0,[newItem]) } }, handleConfirm() { const _self = this _self.validateForm('addTableTestForm').then(res => { if (res) { _self.$emit('confirm',_self.dataTableTestList) console.log(_self.dataTableTestList) } }) } }, created() { }, mounted() { } } </script> <style lang="scss"> .test-table { min-height: 50vh; .ant-table-thead > tr > th { text-align: center; border-bottom-color: transparent !important; } .ant-table-tbody > tr > td { text-align: center; border-bottom-color: transparent !important; } } </style>
用法,所有的属性都放在一个对象中来管理,看个人习惯
<add-test-table v-model="testTableListFrom.isShowTestTable" :title="testTableListFrom.testTableTitle" @hide="handleTestTableHide" :confirm-btn-text="testTableListFrom.testTableActionType=='update'?'Save':'Create'" :confirm-loading="testTableListFrom.testTableLoading" :data-table-test-modal="testTableListFrom.testTableList" @confirm="handleTestTableConfirm" ></add-test-table>
父组件的JS
testTableListFrom: { testTableList: [ ], testTableTitle: '', isShowTestTable: false, testTableActionType: 'create', testTableLoading: false }
handleOpenTable() { const _self = this _self.testTableListFrom.isShowTestTable = true _self.testTableListFrom.testTableActionType = __TEST_TABLE_ACTION_TYPE.CREATE _self.testTableListFrom.testTableTitle = 'Add SKU' _self.testTableListFrom.testTableList = [] }, handleCloseTable() { const _self = this _self.testTableListFrom.isShowTestTable = true _self.testTableListFrom.testTableActionType = __TEST_TABLE_ACTION_TYPE.UPDATE _self.testTableListFrom.testTableTitle = 'Edit SKU' _self.testTableListFrom.testTableList = [ { id:1, name:'11', age: 11 } ] console.log(_self.testTableListFrom.testTableList) }, handleTestTableHide() { const _self = this _self.testTableListFrom.isShowTestTable = false _self.testTableListFrom.testTableTitle = 'Add SKU' _self.testTableListFrom.testTableList = [] }, handleTestTableConfirm(payload) { console.log(payload) const _self = this; let actionUrl = ""; let successTips = ""; if (_self.testTableListFrom.testTableActionType == __TEST_TABLE_ACTION_TYPE.CREATE) { actionUrl = "/sales-order/api/quickitems/create"; successTips = "Created SKU"; } else if (_self.testTableListFrom.testTableActionType == __TEST_TABLE_ACTION_TYPE.UPDATE) { actionUrl = "/sales-order/api/quickitems/update"; successTips = "Edit SKU"; } if (!actionUrl) { return false } console.log(actionUrl,successTips) _self.testTableListFrom.testTableLoading = true setTimeout(() => { _self.testTableListFrom.testTableLoading = false },2000) } },
上面是模拟的,实际开发中,微调就可以用了