2024-8-22 更新:在添加表单列时候 splice(item1,item2, ...itemx), splice添加项的时候 item1 是在前面添加 根据目前的需求是要在后面添加 所以 index 需要加1
具体需求如下图所示:
后端参数格式:
"type": "phoneBooks",
"data": [
{"phone":"","name"":""},
{"phone":"","name"":""},
{"phone":"","name"":""},
] //电话号码 多个逗号分隔设置
先说代码思路:
动态增加表单可以根据表单动态添加。这个在element ui form表单有例子,这里就不做赘叙。
但是很明显这个问题是一个验证规则有两个参数。 根据element 组件验证规则是 v-model prop rules 要一致。所以就会有一个致命问题 那就是智能验证一个。第二个怎么办?
这里我们不妨借鉴一下密码两次输入验证。我在第一个验证里面添加上第二个验证。
最后结果
主要就是这里了。 在自定义验证的时候需要加上 表单动态添加的验证规则,很多人就要问了 index ,_this 是怎么来的 这里是形参 需要在验证添加、
我感觉说的有点乱 不要着急 前面是思路 后面这里我贴上完整代码
/* * @Description: 通讯录 * @Author: china wei * @Date: 2024-08-21 *
@LastEditTime: 2024-08-21 09:42 */
<template>
<div class="phoneBooks">
<div class="pb_cont">
<el-form
:model="dataParam"
ref="pbForm"
label-width="100px"
class="pbc_form"
label-position="top"
>
<el-form-item
v-for="(item, index) in dataParam.data"
:label="'联系人' + (index + 1)"
:key="item.key"
:prop="'data.' + index + '.name'"
:rules="dataRules[index]"
>
<el-input v-model="item.name" placeholder="请输入姓名"></el-input>
<el-input v-model="item.phone" placeholder="请输入电话"></el-input>
<i
class="pbcf_icon el-icon-circle-plus-outline"
@click.prevent="addItemFun(index)"
></i>
<i
:class="[
'pbcf_icon',
'el-icon-remove-outline',
index == 0 && dataParam.data.length == 1 ? 'pbcf_icon_no' : '',
]"
@click.prevent="
index == 0 && dataParam.data.length == 1
? ''
: removeItemFun(index)
"
></i>
</el-form-item>
</el-form>
</div>
<div class="form_btn">
<el-button type="primary" @click="watchControlPanelFun('pbForm')"
>确定</el-button
>
<el-button @click="cancelFun()">取消</el-button>
</div>
</div>
</template>
<script>
import publicVar from "@/commit/publicVar";
const validatePass = (index, _this) => (rule, value, callback) => {
if (!value) {
return callback(new Error("姓名不能为空"));
} else if (!_this.dataParam.data[index].phone) {
return callback(new Error("电话不能为空"));
} else {
if (!publicVar.PHONE.test(_this.dataParam.data[index].phone)) {
return callback(new Error("请输入正确的手机号"));
} else {
return callback();
}
}
};
export default {
name: "phoneBooks",
props: {},
components: {},
data() {
return {
dataParam: {
deviceNoList: [],
type: "pedo",
data: [{ phone: "", name: "" }],
},
dataRules: [
[
{ required: true, message: "请输入活动名称", trigger: "blur" },
{ validator: validatePass(0, this), trigger: "blur" },
],
],
};
},
watch: {},
computed: {},
created() {
this.dataParam.deviceNoList = [this.deviceNo];
},
mounted() {},
methods: {
/**
* @func
* @desc 添加联系人
* @param {}
* @return {}
*/
addItemFun(index) {
this.dataParam.data.splice(index, 0, { phone: "", name: "" });
this.dataRules.splice(index, 0, [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{ validator: validatePass(index, this), trigger: "blur" },
]);
},
/**
* @func
* @desc 删除联系人
* @param {}
* @return {}
*/
removeItemFun(index) {
this.dataParam.data.splice(index, 1);
this.dataRules.splice(index, 1);
},
/**
* @func
* @desc 功能下发
* @param {}
* @return {}
*/
watchControlPanelFun(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$http
.post(this.$api.watchControlPanel, this.dataParam)
.then((res) => {
if (res.statusCode == 200) {
this.$message.success("下发成功");
}
});
} else {
this.$message.console.error("请检查,输入有误");
return false;
}
});
},
// 关闭弹窗
cancelFun() {
Object.assign(this.dataParam.data, this.$options.data().dataParam.data);
this.$emit("cancelFun");
},
},
beforeDestroy() {},
};
</script>
<style lang="scss" scoped>
.phoneBooks {
width: 100%;
height: 542px;
position: relative;
padding-bottom: 40px;
.pb_cont {
width: calc(100% - 40px);
height: calc(100% - 30px);
padding: 30px 20px 0;
overflow-y: auto;
overflow-x: hidden;
.pbc_form {
::v-deep .el-form-item {
.el-form-item__content {
display: flex;
flex-direction: row;
align-items: center;
.el-input {
width: auto;
.el-input__inner {
width: 240px;
height: 32px;
margin-right: 8px;
}
}
.pbcf_icon {
width: 20px;
height: 20px;
font-size: 20px;
margin-right: 8px;
color: #3370ff;
cursor: pointer;
}
.pbcf_icon_no {
color: #999999;
cursor: not-allowed;
}
}
}
}
}
.form_btn {
width: 100%;
position: absolute;
bottom: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: end;
.el-button {
width: 80px;
height: 36px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-weight: 500;
font-size: 14px;
&:first-child {
margin-right: 12px;
}
}
}
}
</style>