实现如下效果
<template> <a-modal title="修改接口定义信息" :width="1200" :visible="visible" :confirmLoading="confirmLoading" @ok="handleSubmit" @cancel="handleCancel" > <a-spin :spinning="formLoading"> <a-form :form="form"> <a-form-item style="display: none;" > <a-input v-decorator="['ifdId']"/> </a-form-item> <a-row :gutter="24"> <a-col :md="12" :sm="24"> <a-form-item label="接口编号" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-input v-bind:disabled="true" v-decorator="['ifdNum']"/> </a-form-item> </a-col> <a-col :md="12" :sm="24"> <a-form-item style="width: 100%" :labelCol="labelCol" :wrapperCol="wrapperCol" label="接口来源" hasFeedback > <a-select style="width: 100%" placeholder="请选择接口来源" v-decorator="['ifdResource', {rules: [{ required: true, message: '请选择接口来源!' }]}]"> <a-select-option v-for="(item,index) in interFaceSource" :key="index" :value="item.id" @click="changeInterfaceResourceFun(item.name)">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> </a-row> <a-row :gutter="24"> <a-col :md="12" :sm="12"> <a-form-item label="来源标识" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-input v-bind:disabled="true" v-decorator="['ifdFlag']"/> </a-form-item> </a-col> <a-col :md="12" :sm="24"> <a-form-item style="width: 100%" :labelCol="labelCol" :wrapperCol="wrapperCol" label="接口通信" hasFeedback > <a-select style="width: 100%" placeholder="请选择接口通信" v-decorator="['ifdSa', {rules: [{ required: true, message: '请选择接口通信!' }]}]"> <a-select-option v-for="(item,index) in saData" :key="index" :value="item.id" @click="changeInterfaceTypeFun(item,'ifdSa')">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> </a-row> <a-row :gutter="24"> <a-col :md="12" :sm="24"> <a-form-item label="接口名称" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-input v-bind:disabled="true" v-decorator="['ifdName']"/> </a-form-item> </a-col> <a-col :md="12" :sm="24"> <a-form-item style="width: 100%" :labelCol="labelCol" :wrapperCol="wrapperCol" label="接口类型" hasFeedback > <a-select style="width: 100%" placeholder="请选择接口类型" v-decorator="['ifdType', {rules: [{ required: true, message: '请选择接口类型!' }]}]"> <a-select-option v-for="(item,index) in typeData" :key="index" :value="item.id" @click="changeInterfaceTypeFun(item,'ifdType')">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> </a-row> <a-row :gutter="24"> <a-col :md="12" :sm="24"> <a-form-item label="前报文类型" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-select style="width: 100%" v-decorator="['ifdPrevtype']"> <a-select-option v-for="(item,index) in prevtypeData" :key="index" :value="item.id">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> <a-col :md="12" :sm="24"> <a-form-item style="width: 100%" :labelCol="labelCol" :wrapperCol="wrapperCol" label="后报文类型" hasFeedback > <a-select style="width: 100%" v-decorator="['ifdAftertype']"> <a-select-option v-for="(item,index) in aftertypeData" :key="index" :value="item.id">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> </a-row> <a-row :gutter="24"> <a-col :md="12" :sm="24"> <a-form-item label="前报文内容" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-textarea style="width: 100%" v-decorator="['ifdPrecontent']"> </a-textarea> </a-form-item> </a-col> <a-col :md="12" :sm="24"> <a-form-item style="width: 100%" :labelCol="labelCol" :wrapperCol="wrapperCol" label="后报文内容" hasFeedback > <a-textarea style="width: 100%" v-decorator="['ifdAftercontent']"> </a-textarea> </a-form-item> </a-col> </a-row> <a-row :gutter="24"> <a-col :md="12" :sm="48"> <a-form-item label="接口描述" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-textarea style="width: 100%" v-decorator="['ifdDesc']"> </a-textarea> </a-form-item> </a-col> </a-row> <a-row :gutter="24"> <a-col :md="12" :sm="24"> <a-form-item label="请求类型" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback > <a-select style="width: 100%" v-decorator="['ifdReqtype']"> <a-select-option v-for="(item,index) in reqtypeData" :key="index" :value="item.id">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> <a-col :md="12" :sm="24"> <a-form-item style="width: 100%" :labelCol="labelCol" :wrapperCol="wrapperCol" label="是否有报文长度" hasFeedback > <a-select style="width: 100%" v-decorator="['ifdMeslength']"> <a-select-option v-for="(item,index) in meslengthData" :key="index" :value="item.id">{ { item.name }} </a-select-option> </a-select> </a-form-item> </a-col> </a-row> </a-form> </a-spin> <div> <a-button class="editable-add-btn" @click="handleAdd"> 添加行 </a-button> <a-table bordered :data-source="dataSource" :columns="columns"> <template slot="ifcId" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcId" v-decorator="['ifcId']"/> </template> <template slot="ifcName" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcName" v-decorator="['ifcName']" @change="e => tableCellChangFun(e.target.value, record, 'ifcName')"/> </template> <template slot="ifcKey" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcKey" v-decorator="['ifcKey']" @change="e => tableCellChangFun(e.target.value, record, 'ifcKey')"/> </template> <template slot="ifcValue" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcValue" v-decorator="['ifcValue']" @change="e => tableCellChangFun(e.target.value, record, 'ifcValue')"/> </template> <template slot="ifcDesc" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcDesc" v-decorator="['ifcDesc']" @change="e => tableCellChangFun(e.target.value, record, 'ifcDesc')"/> </template> <template slot="ifcParkey" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcParkey" v-decorator="['ifcParkey']" @change="e => tableCellChangFun(e.target.value, record, 'ifcParkey')"/> </template> <template slot="ifcLength" slot-scope="text, record" style="width: 10%;"> <a-input :value="record.ifcLength" v-decorator="['ifcLength']" @change="e => tableCellChangFun(e.target.value, record, 'ifcLength')"/> </template> <template slot="ifcNotnull" slot-scope="text, record" style="width: 30%;"> <a-select style="width: 100%" v-decorator="['ifcNotnull']" v-model="record.ifcNotnull" @change="e => tableCellChangFun(e, record, 'ifcNotnull')"> <a-select-option v-for="(item,index) in notnullData" :key="index" :value="item.id">{ { item.name }} </a-select-option> </a-select> </template> <template slot="ifcType" slot-scope="text, record" style="width: 10%;"> <a-select style="width: 100%" v-decorator="['ifcType']" v-model="record.ifcType" @change="e => tableCellChangFun(e, record, 'ifcType')"> <a-select-option v-for="(item,index) in typeTableData" :key="index" :value="item.id">{ { item.name }} </a-select-option> </a-select> </template> <template slot="operation" slot-scope="text, record" style="width: 10%;"> <a-popconfirm v-if="dataSource.length" title="确认删除吗?" @confirm="() => onDelete(record)" > <a href="javascript:;">Delete</a> </a-popconfirm> </template> </a-table> </div> </a-modal> </template> <script> import { getInterfaceMaxNoByFlag, addInterfaceDefInfo, getIFCheckInfoByIfdId, updateInterfaceDefInfo } from "@/api/modular/system/interface"; export default { data() { return { dataSource: [], dataSource_save: [], count: 0, columns: [ { title: '关键字', dataIndex: 'ifcKey', scopedSlots: {customRender: 'ifcKey'}, }, { title: '名称', dataIndex: 'ifcName', scopedSlots: {customRender: 'ifcName'}, }, { title: '必填', dataIndex: 'ifcNotnull', scopedSlots: {customRender: 'ifcNotnull'}, }, { title: '长度', dataIndex: 'ifcLength', scopedSlots: {customRender: 'ifcLength'}, }, { title: '类型', dataIndex: 'ifcType', scopedSlots: {customRender: 'ifcType'}, }, { title: '属性', dataIndex: 'ifcValue', scopedSlots: {customRender: 'ifcValue'}, }, { title: '描述', dataIndex: 'ifcDesc', scopedSlots: {customRender: 'ifcDesc'}, }, { title: '父级', dataIndex: 'ifcParkey', scopedSlots: {customRender: 'ifcParkey'}, }, { title: '扩展', dataIndex: 'ifcExtension', }, { title: '操作', dataIndex: 'operation', scopedSlots: {customRender: 'operation'}, }, ], labelCol: { xs: {span: 24}, sm: {span: 6} }, wrapperCol: { xs: {span: 24}, sm: {span: 16} }, visible: false, confirmLoading: false, formLoading: false, interFaceSource: [ {id: 'INTERFACE_SMS', name: 'SMS'}, {id: 'INTERFACE_AL', name: 'AL'}, { id: 'INTERFACE_CS', name: 'CS' }, {id: 'INTERFACE_RC', name: 'RC'}, {id: 'INTERFACE_OA', name: 'OA'}, {id: 'INTERFACE_FM', name: 'FM'}, {id: 'INTERFACE_PJ', name: 'PJ'}, { id: 'INTERFACE_HM', name: 'HM' }, {id: 'INTERFACE_TM', name: 'TM'} ], //接口来源,先写死,后续再查数据库 saData: [{id: '', name: ''}, {id: '1', name: '发送'}, {id: '2', name: '接收'}], synData: [{id: '0', name: '否'}, {id: '1', name: '是'}], typeData: [{id: '', name: ''}, {id: 'INTERFACE_TYPE_HTTPS', name: 'HTTPS'}, { id: 'INTERFACE_TYPE_HTTP', name: 'HTTP' }, {id: 'INTERFACE_TYPE_WEBSERVICE', name: 'WEBSERVICE'}, {id: 'INTERFACE_TYPE_SOCKET', name: 'SOCKET'}], prevtypeData: [{id: '0', name: '字符串'}, {id: '1', name: 'xml'}, {id: '2', name: 'json'}, {id: '3', name: 'jsp'}], aftertypeData: [{id: '0', name: '字符串'}, {id: '1', name: 'xml'}, {id: '2', name: 'json'}, {id: '3', name: 'jsp'}], reqtypeData: [{id: '', name: ''}, {id: '0', name: 'POST'}, {id: '1', name: 'GET'}, {id: '2', name: 'DELETE'}], meslengthData: [{id: '', name: ''}, {id: '0', name: '是'}, {id: '1', name: '否'}], notnullData: [{id: '1', name: '必填'}, {id: '0', name: '非必填'}], typeTableData: [{id: 'String', name: 'String'}, {id: 'Number', name: 'Number'}, {id: 'Date', name: 'Date'}], form: this.$form.createForm(this), //只有这样注册后,才能通过表单拉去数据 }; }, methods: { // 初始化方法 edit(record) { this.visible = true this.formLoading = false setTimeout(() => { this.form.setFieldsValue( { ifdId: record.ifdId, ifdNum: record.ifdNum, ifdResource: record.ifdResource, ifdFlag: record.ifdFlag, ifdSa: record.ifdSa, ifdName: record.ifdName, ifdType: record.ifdType, ifdPrevtype: record.ifdPrevtype, ifdAftertype: record.ifdAftertype, ifdPrecontent: record.ifdPrecontent, ifdAftercontent: record.ifdAftercontent, ifdDesc: record.ifdDesc, ifdReqtype: record.ifdReqtype, ifdMeslength: record.ifdMeslength } ) }, 100) /*处理表格数据*/ this.getTableDataFun(record.ifdId); }, onDelete(key) { const dataSource = [...this.dataSource]; this.dataSource = dataSource.filter(item => item !== key); this.dataSource_save = this.dataSource; }, handleAdd() { const {count, dataSource} = this; const newData = { ifcKey: '', ifcName: '', ifcNotnull: '', ifcLength: '', ifcType: '', ifcValue: '', ifcDesc: '', ifcParkey: '', ifcExtension: '', ifcId: '' }; this.dataSource = [...dataSource, newData]; this.count = count + 1; this.dataSource_save = this.dataSource; }, handleSubmit() { const {form: {validateFields}} = this this.confirmLoading = true var tableInfo = this.dataSource; validateFields((errors, values) => { if (!errors) { var param = values; param.tableInfo = tableInfo; this.confirmLoading = false updateInterfaceDefInfo(param).then((res) => { if (res.success) { this.$message.success('编辑成功') this.visible = false this.confirmLoading = false this.$emit('ok', values) this.form.resetFields() } else { this.$message.error('编辑失败:' + res.message) } }).finally((res) => { this.confirmLoading = false }) } else { this.confirmLoading = false } }) }, handleCancel() { this.visible = false }, changeInterfaceResourceFun(param) { getInterfaceMaxNoByFlag({'ifdFlag': param}).then((res) => { if (res.success) { this.form.setFieldsValue({ ifdFlag: res.data }); this.changeInterfaceTypeFun(); } else { this.$message.warning(res.message) } }) }, changeInterfaceTypeFun(paramDOM, type) { var saValue = ""; var saText = ""; var typeValue = ""; var typeText = ""; var resourceValue = ""; var resourceText = ""; if (type == 'ifdType') { typeValue = paramDOM.id; typeText = paramDOM.name; saValue = document.getElementById("ifdSa").value; saText = document.getElementById("ifdSa").innerText; } else if (type == 'ifdSa') { saValue = paramDOM.id; saText = paramDOM.name; typeValue = document.getElementById("ifdType").value; typeText = document.getElementById("ifdType").innerText; } else { saValue = document.getElementById("ifdSa").value; saText = document.getElementById("ifdSa").innerText; typeValue = document.getElementById("ifdType").value; typeText = document.getElementById("ifdType").innerText; } resourceValue = document.getElementById("ifdResource").value; resourceText = document.getElementById("ifdResource").innerText; if (resourceValue && saValue && typeValue) { var name = resourceText + "_" + saText + "_" + typeText; this.form.setFieldsValue({ ifdName: name }); } }, tableCellChangFun(value, key, column) { const newData = [...this.dataSource]; const target = newData.filter(item => key === item)[0]; if (target) { target[column] = value; this.dataSource = newData; } }, getTableDataFun(ifdid) { getIFCheckInfoByIfdId({'ifdId': ifdid}).then((res) => { if (res.success) { var dataArray = res.data; var array = []; for (var i = 0; i < dataArray.length; i++) { const newData = { ifcKey: dataArray[i].ifcKey, ifcName: dataArray[i].ifcName, ifcNotnull: dataArray[i].ifcNotnull, ifcLength: dataArray[i].ifcLength, ifcType: dataArray[i].ifcType, ifcValue: dataArray[i].ifcValue, ifcDesc: dataArray[i].ifcDesc, ifcParkey: dataArray[i].ifcParkey, ifcExtension: dataArray[i].ifcExtension, ifcId: dataArray[i].ifcId } array.push(newData); } this.dataSource = array; } else { this.$message.warning(res.message) } }) } }, }; </script> <style> .editable-cell { position: relative; } .editable-cell-input-wrapper, .editable-cell-text-wrapper { padding-right: 24px; } .editable-cell-text-wrapper { padding: 5px 24px 5px 5px; } .editable-cell-icon, .editable-cell-icon-check { position: absolute; right: 0; width: 20px; cursor: pointer; } .editable-cell-icon { line-height: 18px; display: none; } .editable-cell-icon-check { line-height: 28px; } .editable-cell:hover .editable-cell-icon { display: inline-block; } .editable-cell-icon:hover, .editable-cell-icon-check:hover { color: #108ee9; } .editable-add-btn { margin-bottom: 8px; } /*下拉列表高度*/ .ant-select-dropdown-menu-item { height: 30px; } </style>
备注:
表单信息就不做详细的解释了,主要是表格信息
在vue官网上没有找到这种整个表格一起提交的,所以就按照自己的想法弄了一下,也是刚开始学vue,不知道写法好不好,具体写法如下:
表格中的每个单元格都是用模板定义的,
slot : 跟jQuery的Id差不多,
slot-scope : text具体忘记了,但是record是当前的行数据,里面是json格式的,用来表格新增行的时候给模板赋值 :value 给模板赋值,可以用来维护页的时候,读取数据,可以参考上面的代码.
表格中的 dataSource 为表格数据源
保存时候的逻辑是,给每个单元格加上chang事件,更新值的时候去更新模板中的数据,然后添加到dataSource中,之后一起提交.
至于表格下面的分页,还没来得及找,后续再说吧