最终效果如下图,没填的会报空,填了的则正常
弹窗代码如下(直接复制肯定跑不了,自己设计一个按钮添加点击事件改变dialogAddVisible来显示)
<a-modal title="新增敏感词" centered :width="864" :visible="dialogAddVisible" :confirm-loading="confirmLoading" ok-text="确认" @ok="onSubmit" @cancel="dialogAddVisible = false" > <a-form-model :model="addForm" ref="addForm"> <a-table class="addForm" :columns="addColumns" :dataSource="dataSource" :pagination="false"> <div slot="word" slot-scope="text, record, index"> <a-form-model-item ref="word" :prop="`word[${index}]`" :rules="{ required: true, message: '敏感词不能为空', trigger: 'blur' }" > <a-input style="width: 288px" v-model="addForm.word[index]" /> </a-form-model-item> </div> <div slot="type" slot-scope="text, record, index"> <a-form-model-item :prop="`typee[${index}]`" :rules="{ required: true, message: '敏感词不能为空', trigger: 'blur' }" > <a-select style="width: 288px" placeholder="请选择分类" v-model="addForm.typee[index]"> <a-select-option v-for="item in typeOption" :key="item.id" :label="item.type" :value="item.type"> {{ item.type }} </a-select-option> </a-select> </a-form-model-item> </div> <div slot="opreate" slot-scope="text, record"> <a class="removeRowBTN" href="javascript:;" style="color: #3370ff" @click="handleDeleteAdd(text, record)" >删除</a > </div> </a-table> </a-form-model> <div style="height: 48px; line-height: 48px; text-align: center"> <a-icon style="color: rgba(51, 112, 255, 1); font-size: 11px; margin-right: 10px" type="plus" /> <a style="color: rgba(51, 112, 255, 1)" @click="addRow">添加行</a> </div> </a-modal>
复制
部分使用到的data或者方法如下,拷贝进去可能不能运行,主要是分享一下思路。
每需要添加一行就往table的datasource里添加一个空数据站位字,使得表格多出一行,而重点是如何准确的获取每一行的数据并且监听和校验呢?
我设计的form叫addForm,里面的word和type是个数组,专门存对应的数据。在a-form-model里使用:form=“addForm”。重点来了,a-form-model-item的prop属性,这个我观察了官网的例子,发现,prop需要赋一个字符串,字符串的内容是form的属性,在这里,form的属性则是word和type这两个数组,又因为我有许多输入框,我用的是数组来对应那些输入框。所以prop应该是动态的,(每个输入框的prop不一样嘛),则写出了:prop="`word[${index}]`"。让prop等于word[0]/word[1]/word[2]这样。而input中的v-model也是对应着那个数据。从而达到了校验表单的效果
export default { name: 'Sensitive', data() { return { template: { key: 1, word: '', type: '', opreate: '', }, dataSource: [], dialogAddVisible: false, tempItem: { word: '', type: '', }, addForm: { word: [], typee: [], }, rules: { word: [{ required: true, message: '敏感词不能为空', trigger: 'blur' }], typee: [{ required: true, message: '请填写类型', trigger: 'blur' }], }, dialogEditVisible: false, showColumns: [ { title: '敏感词', dataIndex: 'word', width: 'auto', key: 'name', fontSize: 14, }, { title: '分类', dataIndex: 'type', key: 'age', width: 320, filters: [ { text: '谩骂骚扰', value: '谩骂骚扰' }, { text: '暴力言论', value: '暴力言论' }, { text: '政治', value: '政治' }, { text: '贩卖野生动物', value: '贩卖野生动物' }, { text: '色情挑逗', value: '色情挑逗' }, { text: '色情传播', value: '色情传播' }, { text: '广告引流', value: '广告引流' }, ], onFilter: (value, record) => { // 这里要设置一下分页器的总数 return record.type == value }, }, { title: '操作', dataIndex: 'opreate', key: 'opreate', ellipsis: true, width: 112, scopedSlots: { customRender: 'opreate' }, }, ], addColumns: [ { title: '数量', dataIndex: 'key', width: 80, key: 'key', fontSize: 14, }, { title: '敏感词', dataIndex: 'word', width: 320, key: 'name', fontSize: 14, scopedSlots: { customRender: 'word' }, }, { title: '分类', dataIndex: 'type', key: 'age', width: 320, scopedSlots: { customRender: 'type' }, }, { title: '操作', dataIndex: 'opreate', key: 'opreate', ellipsis: true, width: 80, scopedSlots: { customRender: 'opreate' }, }, ], typeOption: [ { type: '谩骂骚扰', id: 1 }, { type: '暴力言论', id: 2 }, { type: '政治', id: 3 }, { type: '贩卖野生动物', id: 4 }, { type: '色情挑逗', id: 5 }, { type: '色情传播', id: 6 }, { type: '广告引流', id: 7 }, ], dialogPvVisible: false, } }, created() { // 深拷贝一份进去 this.dataSource.push(JSON.parse(JSON.stringify(this.template))) }, methods: { // 判断删除状态,如果只有一项则不可操作,反之亦然 judgeAvailable() { console.log('asd') if (this.dataSource.length == 1) { let deleteBTN = document.getElementsByClassName('removeRowBTN')[0] deleteBTN.style.cursor = 'not-allowed' deleteBTN.style.color = 'grey' deleteBTN.style.pointerEvents = 'none' } else { var x = document.getElementsByClassName('removeRowBTN') var i for (i = 0; i < x.length; i++) { x[i].style.cursor = 'pointer' x[i].style.color = '#3370ff' x[i].style.pointerEvents = 'all' } } }, showAddDialog() { this.dialogAddVisible = true this.$nextTick(() => { this.judgeAvailable() }) }, addRow() { let obj = JSON.parse(JSON.stringify(this.template)) obj.key = this.dataSource[this.dataSource.length - 1].key + 1 this.dataSource.push(obj) console.log(this.addForm) this.judgeAvailable() }, // 新增敏感词的校验 onSubmit() { this.$refs.addForm.validate((valid) => { if (valid) { console.log(this.dataSource) console.log(this.addForm) alert('submit!') } else { console.log('error submit!!') console.log(this.dataSource) console.log(this.addForm) console.log(typeof this.addForm.typee[0]) return false } }) }, showEditWordDialog(text, record) { this.dialogEditVisible = true this.$nextTick(() => { this.editForm.setFieldsValue({ editSensitiveWord: record.word }) this.editForm.setFieldsValue({ editType: record.type }) }) }, // 新增敏感词 handleAddWord() {}, showEditDialog(text, record) { console.log(text, record) }, handleDeleteAdd(text, record) { const h = this.$createElement console.log(text, record) this.$confirm({ title: `你确认要删除【${record.word}】敏感词吗`, okText: '确认', cancelText: '取消', centered: true, icon: () => h('img', { attrs: { src: require('../../assets/images/alert.png'), }, style: { 'vertical-align': 'baseline', display: 'inline', float: 'left', 'margin-right': '17px', }, }), onOk: () => { console.log('确认删除新增项') this.dataSource.splice(record.key - 1, 1) if (this.dataSource.length == 1) { // 设置为不可用 this.judgeAvailable() return } // 这里发送删除的请求,不过需要key,等后端的数据吧 }, }) }, },
复制