<template>
<div class="bgf">
<div class="flex">
<span class="fs_16 bold color_333">动态表单验证</span>
<div class="flex_c">
<p class="btn fs_14 flex_cen color add" @click="addRow"><span class="el-icon-plus"></span> 添加一行</p>
<p class="btn fs_14 flex_cen info_color" @click="delRow"><span class="el-icon-close"></span> 删除</p>
</div>
</div>
<el-form ref="forms" :model="forms">
<el-table ref="multipleTable" :data="forms.tableData" tooltip-effect="dark" border style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55">
</el-table-column>
<el-table-column label="编号" width="80">
<template #default="{ row }">
{{row.index}}
</template>
</el-table-column>
<el-table-column label="姓名" width="80">
<template #default="{ row, $index }">
<el-form-item v-if="$index>=0" :prop="`tableData.${$index}.realname`" :rules="rules.realname">
<el-input type="text" placeholder="输入姓名" v-model.trim="row.realname"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="身份证号" show-overflow-tooltip>
<template #default="{ row, $index }">
<el-form-item v-if="$index>=0" :prop="`tableData.${$index}.idcard`" :rules="rules.idcard">
<el-input type="text" placeholder="输入身份证号" :class="{err: row.error&&!row.error.idcard}" v-model.trim="row.idcard"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="手机号码" show-overflow-tooltip>
<template #default="{ row, $index }">
<el-form-item v-if="$index>=0" :prop="`tableData.${$index}.mobile`" :rules="rules.mobile">
<el-input type="number" placeholder="输入手机号码" :class="{err: row.error&&!row.error.mobile}" v-model.trim="row.mobile"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="备注" show-overflow-tooltip>
<template #default="{ row }">
<el-form-item prop="remark">
<el-input type="text" placeholder="输入备注" v-model.trim="row.remark"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
</div>
</template>
<script>
function isPhone(value) {
const reg = /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57]|19[0-9])[0-9]{8}$/
return reg.test(value)
}
function isIdCard(value) {
const reg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
return reg.test(value)
}
var checkIdcard = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入身份证号'))
} else if (!isIdCard(value)) {
callback(new Error('请输入正确的身份证号'))
} else {
callback()
}
}
var checkMobile = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入手机号码'))
} else if (!isPhone(value)) {
callback(new Error('请输入正确的手机号码'))
} else {
callback()
}
}
export default {
name: 'TaxesTable',
data() {
return {
forms: {
tableData: [ {
index: 1,
realname: '',
idcard: '',
mobile: '',
remark: ''
} ]
},
multipleSelection: [],
rules: {
realname: [ { required: true, message: '', trigger: 'blur' } ],
mobile: [ { validator: checkMobile, trigger: 'blur' } ],
idcard: [ { validator: checkIdcard, trigger: 'blur' } ]
}
}
},
methods: {
handleSelectionChange(val) {
this.multipleSelection = val
},
addRow() {
let index = 1
if (this.forms.tableData.length != 0) {
index = this.forms.tableData[this.forms.tableData.length - 1].index + 1
}
this.forms.tableData.push({
index,
realname: '',
idcard: '',
mobile: '',
remark: ''
})
if(this.$parent.disabled) {
this.$parent.disabled = false
}
},
delRow() {
if (this.multipleSelection.length == 0) return
if (this.multipleSelection.length == this.forms.tableData.length) {
this.forms.tableData = []
} else {
for (let i = this.forms.tableData.length - 1; i >= 0; i--) {
for (let n = 0; n < this.multipleSelection.length; n++) {
if (this.forms.tableData[i].index == this.multipleSelection[n].index) {
this.forms.tableData.splice(i, 1)
}
}
}
}
this.multipleSelection = []
this.$refs.multipleTable.clearSelection()
if(!this.$parent.disabled) {
if(this.forms.tableData.length==0){
this.$parent.disabled = true
}
}
},
ruleForms(cb) {
this.$refs.forms.validate((valid) => {
if (valid) {
cb && cb()
}
})
}
}
}
</script>
<style lang='less' scoped>
.flex {
display: flex !important;
align-items: center;
justify-content: space-between;
}
.flex_c {
display: flex !important;
align-items: center;
}
.flex_cen {
display: flex;
align-items: center;
justify-content: center;
}
.fs_14 {
font-size: 14px !important;
}
.fs_15 {
font-size: 15px !important;
}
.fs_16 {
font-size: 16px !important;
}
.btn {
width: 117px;
height: 32px;
border-radius: 4px;
border: 1px solid #a2aec7;
margin-left: 20px;
&.add {
border-color: #1890ff;
}
}
/deep/.el-table {
margin-top: 20px;
thead {
color: #333;
}
/deep/thead th {
background: #e7ecf6 !important;
border-color: #fff;
}
.cell {
text-align: center !important;
}
.err {
.el-input__inner {
// color: #ff4e4e;
border-color: #ff4e4e;
}
}
.el-input__inner {
padding: 0;
border-color: #fff;
font-size: 12px;
height: 24px;
text-align: center;
}
.el-form-item.is-error .el-input__inner {
border-color: #f56c6c;
}
.el-form-item--small.el-form-item {
margin-bottom: 0;
}
.el-form-item--small .el-form-item__content,
.el-form-item--small .el-form-item__label,
.el-input--small .el-input__icon {
line-height: 24px;
}
}
.submit {
width: 200px;
line-height: 24px;
}
</style>