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>