el-form动态增减表单项

在这里插入图片描述
1、想要实现如上图的效果,动态增加表单项并进行校验,校验规则可以直接在需要的 <el-form-item中直接添加:rules=“校验规则”。

2、prop是动态生成的,至于:prop为什么是:prop="‘hostConfig.’ + index + ‘.ip’"这种形式是可以公式来反推的。根本原因还是prop和v-mode绑定值是要对应上的。

3、根据公式倒推 :prop,公式: 动态校验项的v-model的绑定值 = el-form的属性 :model的值 + ‘.’ + :prop属性的值

4、例如:v-model=“domain.ip” 其实最终就是v-model= “form.hostConfig[index].ip”,而且 中 :model=“form”,所以得到 :prop = ‘hostConfig.’ + index + ‘.ip’。比如prop真实就是:prop=‘hostConfig.0.ip’ prop=‘hostConfig.1.ip’

在这里插入图片描述

实现代码

<template>
  <div
    class="ipConfig page-box"
  >
    <dataCard :title="$t('SYSLOG配置')">
      <div
        class="wrap"
      >
        <el-form
          ref="form"
          label-width="120px"
          :model="form"
          label-position="top"
          :rules="rules"
        >
          <el-row :gutter="30">
            <el-col
              :span="24"
            >
              <el-form-item
                prop=""
              >
                <span slot="label">
                  <tip :msg="$t('是否启用sysLog')">
                    <span>{{ $t('是否启用') }}</span>
                  </tip>
                </span>
                <dataSwitch
                  v-model="form.used"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col
              :span="24"
            >
              <el-form-item
                label="日志类型"
                prop=""
              >
                <el-checkbox-group v-model="checkList">
                  <el-checkbox label="1">
                    资产日志
                  </el-checkbox>
                  <el-checkbox label="2">
                    告警日志
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row
            v-for="(domain, index) in form.hostConfig"
            :key="domain.key"
            :gutter="30"
            style="display: flex;align-items: center;"
          >
            <el-col :span="7">
              <el-form-item
                :label="$t('服务器地址')"
                :prop="'hostConfig.' + index + '.ip'"
                :rules="rules.ip"
              >
                <dataInput
                  v-model="domain.ip"
                  :placeholder="$t('lang.pleaseInput')"
                />
              </el-form-item>
            </el-col>
            <el-col :span="7">
              <el-form-item
                :label="$t('协议')"
                :prop="'hostConfig.' + index + '.protocol'"
                :rules="rules.protocol"
              >
                <data-select
                  v-model="domain.protocol"
                  :options="options"
                  label-key="label"
                  value-key="value"
                />
              </el-form-item>
            </el-col>
            <el-col :span="7">
              <el-form-item
                :label="$t('端口')"
                :prop="'hostConfig.' + index + '.port'"
                :rules="rules.port"
              >
                <dataInput
                  v-model="domain.port"
                  :placeholder="$t('lang.pleaseInput')"
                />
              </el-form-item>
            </el-col>
            <el-col :span="3">
              <i
                v-if="index == 0"
                class="el-icon-plus"
                @click="addForm"
              />
              <i
                v-if="index !== 0"
                class="el-icon-minus"
                @click="reduceForm(index)"
              />
            </el-col>
          </el-row>
        </el-form>
      </div>
      <div slot="footer">
        <loadingButton :method="handleformSure" />
        <el-button
          v-preventReClick
          type="info"
          size="small"
          @click="handleCancel"
        >
          {{ $t("lang.cancel") }}
        </el-button>
      </div>
    </dataCard>
  </div>
</template>
<script>
import api from '@/modules/soc-icsmp/api/system/index'
import rule from '@/frame/lib/rules'
export default {
  data () {
    return {
      form: {
        hostConfig: [{
          ip: '',
          protocol: '',
          port: ''
        }]
      },
      dataArr: [],
      options: [{
        value: 1,
        label: 'UDP'
      }, {
        value: 2,
        label: 'TCP'
      }],
      checkList: []
    }
  },
  computed: {
    rules () {
      const isIPv4 = /^([1-9]|[1-9]\d|1\d\d|2[0-1]\d|22[0-3])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$/
      var valueIsIPv4 = (rule, value, callback) => {
        if (value && !isIPv4.test(value)) {
          return callback(new Error('服务器地址格式不正确'))
        }
        let ipList = this.form.hostConfig.map(item => item.ip)
        if (new Set(ipList).size !== ipList.length) {
          return callback(new Error('服务器地址不可相同,请检查!'))
        }
        callback()
      }
      return {
        protocol: [
          {
            required: true,
            message: this.$t(`lang.pleaseSelect`),
            trigger: [`blur`]
          }
        ],
        ip: [
          {
            required: true,
            message: this.$t(`lang.pleaseInput`),
            trigger: [`blur`]
          },
          { validator: valueIsIPv4, trigger: ['change', `blur`] }
        ],
        port: [
          {
            required: true,
            message: this.$t(`lang.pleaseInput`),
            trigger: [`blur`]
          },
          { validator: rule.valueIsPort, trigger: ['change', `blur`] }
        ]
      }
    }
  },
  watch: {},
  created () {
    this.getData()
  },
  methods: {
    // 表单项增加
    addForm () {
      if (this.form.hostConfig.length >= 3) {
        this.warning('最多可以配置三组服务器地址!')
        return
      }
      this.form.hostConfig.push({
        ip: '',
        protocol: '',
        port: '',
        key: Date.now()
      })
    },
    reduceForm (index) {
      this.form.hostConfig.splice(index, 1)
    },
    handleCancel () {
      this.$nextTick(() => {
        this.$refs.form.clearValidate()
      })
    },
    handleformSure () {
      return new Promise((resolve, reject) => {
        this.$refs.form.validate((valid) => {
          if (valid) {
            let logType = this.checkList.length > 0 ? this.checkList.join(',') : ''
            let params = Object.assign({}, this.form, { 'logType': logType })
            api
              .saveSyslog(params)
              .then((res) => {
                resolve()
                this.success('操作成功')
              })
              .catch((err) => {
                reject()
                this.error((err && err.resp_msg) || this.$t(`lang.error`))
              })
          } else {
            reject()
          }
        })
      })
    },
    getData () {
      api
        .querySyslog()
        .then((res) => {
          res = res || []
          this.checkList = res.logType ? res.logType.split(',') : []
          this.form = res
          this.form.hostConfig = res.hostConfig.length > 0 ? res.hostConfig : [{
            ip: '',
            protocol: '',
            port: ''
          }]
        })
        .catch((err) => {
          this.error(err.resp_msg)
        })
    }
  }
}
</script>
<style lang="scss" scoped>
.ipConfig {
  width: 100%;
  .dataCard {
    margin-bottom: 8px;
  }
  .wrap {
    padding: 10px 30px;
    .dataTip {
      display: inline-block !important;
    }
    .el-icon-plus, .el-icon-minus {
      cursor: pointer;
      color: red;
      font-weight: bold;
      font-size: 20px;
    }
  }
}
.el-loading-spinner{
  .el-loading-text{
    font-size: 18px;
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值