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

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

 

弹窗代码如下(直接复制肯定跑不了,自己设计一个按钮添加点击事件改变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,等后端的数据吧
        },
      })
    },
  },

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ant-design-vue 表单组件的使用方式和 antd(Ant Design for React)类似,但是有些差异。其,a-form-model 并不存在于 ant-design-vue 。相反,ant-design-vue 提供了 a-form 和 a-form-item 两个组件来实现表单的双向绑定。 a-form 组件是最基本的表单组件,用于包裹整个表单,它可以接收一个 model 属性,用于绑定表单数据。a-form-item 组件用于包裹具体的表单项,例如输入框、下拉框、单选框等等。a-form-item 组件也可以接收一个 model 属性,用于绑定表单该项的数据。 以下是一个简单的 ant-design-vue 表单示例: ``` <template> <a-form :model="form" :rules="rules"> <a-form-item label="用户名" prop="username"> <a-input v-model="form.username" /> </a-form-item> <a-form-item label="密码" prop="password"> <a-input v-model="form.password" type="password" /> </a-form-item> <a-form-item> <a-button type="primary" @click="submitForm">提交</a-button> </a-form-item> </a-form> </template> <script> export default { data() { return { form: { username: '', password: '' }, rules: { username: [ { required: true, message: '请输入用户名', trigger: 'blur' } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' } ] } } }, methods: { submitForm() { this.$refs.form.validate(valid => { if (valid) { // 表单验证通过,提交表单数据 console.log(this.form) } else { // 表单验证失败 console.log('error submit!!') return false } }) } } } </script> ``` 在这个示例,我们使用了 a-form 和 a-form-item 组件来实现表单的双向绑定,并使用了 rules 属性来定义表单验证规则。在提交表单时,我们使用了 $refs.form.validate 方法来验证表单数据是否符合规则。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值