当前位置:   article > 正文

Ant-Design-Vue中,a-form-model嵌套table,并且支持动态添加输入框还支持表单校验

a-form-model

最终效果如下图,没填的会报空,填了的则正常

 

弹窗代码如下(直接复制肯定跑不了,自己设计一个按钮添加点击事件改变dialogAddVisible来显示)

  1. <a-modal
  2. title="新增敏感词"
  3. centered
  4. :width="864"
  5. :visible="dialogAddVisible"
  6. :confirm-loading="confirmLoading"
  7. ok-text="确认"
  8. @ok="onSubmit"
  9. @cancel="dialogAddVisible = false"
  10. >
  11. <a-form-model :model="addForm" ref="addForm">
  12. <a-table class="addForm" :columns="addColumns" :dataSource="dataSource" :pagination="false">
  13. <div slot="word" slot-scope="text, record, index">
  14. <a-form-model-item
  15. ref="word"
  16. :prop="`word[${index}]`"
  17. :rules="{ required: true, message: '敏感词不能为空', trigger: 'blur' }"
  18. >
  19. <a-input style="width: 288px" v-model="addForm.word[index]" />
  20. </a-form-model-item>
  21. </div>
  22. <div slot="type" slot-scope="text, record, index">
  23. <a-form-model-item
  24. :prop="`typee[${index}]`"
  25. :rules="{ required: true, message: '敏感词不能为空', trigger: 'blur' }"
  26. >
  27. <a-select style="width: 288px" placeholder="请选择分类" v-model="addForm.typee[index]">
  28. <a-select-option v-for="item in typeOption" :key="item.id" :label="item.type" :value="item.type">
  29. {{ item.type }}
  30. </a-select-option>
  31. </a-select>
  32. </a-form-model-item>
  33. </div>
  34. <div slot="opreate" slot-scope="text, record">
  35. <a class="removeRowBTN" href="javascript:;" style="color: #3370ff" @click="handleDeleteAdd(text, record)"
  36. >删除</a
  37. >
  38. </div>
  39. </a-table>
  40. </a-form-model>
  41. <div style="height: 48px; line-height: 48px; text-align: center">
  42. <a-icon style="color: rgba(51, 112, 255, 1); font-size: 11px; margin-right: 10px" type="plus" />
  43. <a style="color: rgba(51, 112, 255, 1)" @click="addRow">添加行</a>
  44. </div>
  45. </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也是对应着那个数据。从而达到了校验表单的效果

  1. export default {
  2. name: 'Sensitive',
  3. data() {
  4. return {
  5. template: {
  6. key: 1,
  7. word: '',
  8. type: '',
  9. opreate: '',
  10. },
  11. dataSource: [],
  12. dialogAddVisible: false,
  13. tempItem: {
  14. word: '',
  15. type: '',
  16. },
  17. addForm: {
  18. word: [],
  19. typee: [],
  20. },
  21. rules: {
  22. word: [{ required: true, message: '敏感词不能为空', trigger: 'blur' }],
  23. typee: [{ required: true, message: '请填写类型', trigger: 'blur' }],
  24. },
  25. dialogEditVisible: false,
  26. showColumns: [
  27. {
  28. title: '敏感词',
  29. dataIndex: 'word',
  30. width: 'auto',
  31. key: 'name',
  32. fontSize: 14,
  33. },
  34. {
  35. title: '分类',
  36. dataIndex: 'type',
  37. key: 'age',
  38. width: 320,
  39. filters: [
  40. { text: '谩骂骚扰', value: '谩骂骚扰' },
  41. { text: '暴力言论', value: '暴力言论' },
  42. { text: '政治', value: '政治' },
  43. { text: '贩卖野生动物', value: '贩卖野生动物' },
  44. { text: '色情挑逗', value: '色情挑逗' },
  45. { text: '色情传播', value: '色情传播' },
  46. { text: '广告引流', value: '广告引流' },
  47. ],
  48. onFilter: (value, record) => {
  49. // 这里要设置一下分页器的总数
  50. return record.type == value
  51. },
  52. },
  53. {
  54. title: '操作',
  55. dataIndex: 'opreate',
  56. key: 'opreate',
  57. ellipsis: true,
  58. width: 112,
  59. scopedSlots: { customRender: 'opreate' },
  60. },
  61. ],
  62. addColumns: [
  63. {
  64. title: '数量',
  65. dataIndex: 'key',
  66. width: 80,
  67. key: 'key',
  68. fontSize: 14,
  69. },
  70. {
  71. title: '敏感词',
  72. dataIndex: 'word',
  73. width: 320,
  74. key: 'name',
  75. fontSize: 14,
  76. scopedSlots: { customRender: 'word' },
  77. },
  78. {
  79. title: '分类',
  80. dataIndex: 'type',
  81. key: 'age',
  82. width: 320,
  83. scopedSlots: { customRender: 'type' },
  84. },
  85. {
  86. title: '操作',
  87. dataIndex: 'opreate',
  88. key: 'opreate',
  89. ellipsis: true,
  90. width: 80,
  91. scopedSlots: { customRender: 'opreate' },
  92. },
  93. ],
  94. typeOption: [
  95. { type: '谩骂骚扰', id: 1 },
  96. { type: '暴力言论', id: 2 },
  97. { type: '政治', id: 3 },
  98. { type: '贩卖野生动物', id: 4 },
  99. { type: '色情挑逗', id: 5 },
  100. { type: '色情传播', id: 6 },
  101. { type: '广告引流', id: 7 },
  102. ],
  103. dialogPvVisible: false,
  104. }
  105. },
  106. created() {
  107. // 深拷贝一份进去
  108. this.dataSource.push(JSON.parse(JSON.stringify(this.template)))
  109. },
  110. methods: {
  111. // 判断删除状态,如果只有一项则不可操作,反之亦然
  112. judgeAvailable() {
  113. console.log('asd')
  114. if (this.dataSource.length == 1) {
  115. let deleteBTN = document.getElementsByClassName('removeRowBTN')[0]
  116. deleteBTN.style.cursor = 'not-allowed'
  117. deleteBTN.style.color = 'grey'
  118. deleteBTN.style.pointerEvents = 'none'
  119. } else {
  120. var x = document.getElementsByClassName('removeRowBTN')
  121. var i
  122. for (i = 0; i < x.length; i++) {
  123. x[i].style.cursor = 'pointer'
  124. x[i].style.color = '#3370ff'
  125. x[i].style.pointerEvents = 'all'
  126. }
  127. }
  128. },
  129. showAddDialog() {
  130. this.dialogAddVisible = true
  131. this.$nextTick(() => {
  132. this.judgeAvailable()
  133. })
  134. },
  135. addRow() {
  136. let obj = JSON.parse(JSON.stringify(this.template))
  137. obj.key = this.dataSource[this.dataSource.length - 1].key + 1
  138. this.dataSource.push(obj)
  139. console.log(this.addForm)
  140. this.judgeAvailable()
  141. },
  142. // 新增敏感词的校验
  143. onSubmit() {
  144. this.$refs.addForm.validate((valid) => {
  145. if (valid) {
  146. console.log(this.dataSource)
  147. console.log(this.addForm)
  148. alert('submit!')
  149. } else {
  150. console.log('error submit!!')
  151. console.log(this.dataSource)
  152. console.log(this.addForm)
  153. console.log(typeof this.addForm.typee[0])
  154. return false
  155. }
  156. })
  157. },
  158. showEditWordDialog(text, record) {
  159. this.dialogEditVisible = true
  160. this.$nextTick(() => {
  161. this.editForm.setFieldsValue({ editSensitiveWord: record.word })
  162. this.editForm.setFieldsValue({ editType: record.type })
  163. })
  164. },
  165. // 新增敏感词
  166. handleAddWord() {},
  167. showEditDialog(text, record) {
  168. console.log(text, record)
  169. },
  170. handleDeleteAdd(text, record) {
  171. const h = this.$createElement
  172. console.log(text, record)
  173. this.$confirm({
  174. title: `你确认要删除【${record.word}】敏感词吗`,
  175. okText: '确认',
  176. cancelText: '取消',
  177. centered: true,
  178. icon: () =>
  179. h('img', {
  180. attrs: {
  181. src: require('../../assets/images/alert.png'),
  182. },
  183. style: {
  184. 'vertical-align': 'baseline',
  185. display: 'inline',
  186. float: 'left',
  187. 'margin-right': '17px',
  188. },
  189. }),
  190. onOk: () => {
  191. console.log('确认删除新增项')
  192. this.dataSource.splice(record.key - 1, 1)
  193. if (this.dataSource.length == 1) {
  194. // 设置为不可用
  195. this.judgeAvailable()
  196. return
  197. }
  198. // 这里发送删除的请求,不过需要key,等后端的数据吧
  199. },
  200. })
  201. },
  202. },

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/91605
推荐阅读
相关标签
  

闽ICP备14008679号