<template>
<div class="dynamic" style="margin-top: 50px">
<div class="left">
<el-form
:model="dynamicForm"
label-width="200px"
:rules="dynamicFormRules"
ref="dynamicForm"
>
<el-form-item label="表单类型">
<el-radio-group v-model="dynamicForm.formType" @change="radioChange">
<el-radio v-for="(itemRadio,indexRadio) in radioArray" :key="indexRadio" :label="itemRadio.value">{{itemRadio.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="key(v-model绑定的值)" prop="key">
<el-input
v-model.trim="dynamicForm.key"
@blur="keyInputBlur($event)"
/>
</el-form-item>
<el-form-item label="label(el-form-item的label)" prop="name">
<el-input
v-model.trim="dynamicForm.name"
@blur="keyInputBlur($event)"
/>
</el-form-item>
<!-- 单选按钮 -->
<div v-if="dynamicForm.formType == 2">
<div v-for="(item, index) in dynamicForm.radioArr" :key="index">
<el-form-item
:prop="`radioArr.${index}.keyRadio`"
:rules="[
{
required: true,
message: '请输入单选按钮的key',
trigger: 'blur',
},
{
pattern: /^[A-Za-z-]+$/,
message: '只允许输入英文字母',
trigger: ['blur', 'change'],
},
]"
>
<span slot="label">{{ "单选选项key" + (index + 1) }}</span>
<el-input
v-model.trim="dynamicForm.radioArr[index].keyRadio"
@blur="radioKeyBlur($event, 'key')"
>
<el-button
v-if="index == 0"
slot="append"
icon="el-icon-plus"
@click.native="addRadioItem('radio')"
></el-button>
<el-button
v-if="index != 0 && index != 1"
slot="append"
icon="el-icon-minus"
@click.native="removeRadioItem(index, 'radio')"
></el-button>
</el-input>
</el-form-item>
<el-form-item
:prop="`radioArr.${index}.value`"
:rules="[
{ required: true, message: '请输入value', trigger: 'blur' },
{
pattern: /^[\u4e00-\u9fa5]+(·[\u4e00-\u9fa5]+)*$/,
message: '只允许输入汉字',
trigger: ['blur', 'change'],
},
]"
>
<span slot="label">{{ "单选选项value" + (index + 1) }}</span>
<el-input
v-model.trim="dynamicForm.radioArr[index].value"
@blur="radioKeyBlur($event, 'value')"
/>
</el-form-item>
</div>
</div>
<!-- select选择器 -->
<div v-if="dynamicForm.formType == 6">
<div
v-for="(itemSelect, indexSelect) in dynamicForm.selectArr"
:key="indexSelect"
>
<el-form-item
:prop="`selectArr.${indexSelect}.keySelect`"
:rules="[
{
required: true,
message: '请输入select选择器的key',
trigger: 'blur',
},
{
pattern: /^[A-Za-z-]+$/,
message: '只允许输入英文字母',
trigger: ['blur', 'change'],
},
]"
>
<span slot="label">{{
"select选择器key" + (indexSelect + 1)
}}</span>
<el-input
v-model.trim="dynamicForm.selectArr[indexSelect].keySelect"
@blur="selectKeyBlur($event, 'key')"
>
<el-button
v-if="indexSelect == 0"
slot="append"
icon="el-icon-plus"
@click.native="addRadioItem('select')"
></el-button>
<el-button
v-if="indexSelect != 0 && indexSelect != 1"
slot="append"
icon="el-icon-minus"
@click.native="removeRadioItem(indexSelect, 'select')"
></el-button>
</el-input>
</el-form-item>
<el-form-item
:prop="`selectArr.${indexSelect}.selectValue`"
:rules="[
{ required: true, message: '请输入value', trigger: 'blur' },
{
pattern: /^[\u4e00-\u9fa5]+(·[\u4e00-\u9fa5]+)*$/,
message: '只允许输入汉字',
trigger: ['blur', 'change'],
},
]"
>
<span slot="label">{{
"select选择器value" + (indexSelect + 1)
}}</span>
<el-input
v-model.trim="dynamicForm.selectArr[indexSelect].selectValue"
@blur="selectKeyBlur($event, 'value')"
/>
</el-form-item>
</div>
</div>
<!-- 复选框 -->
<div v-if="dynamicForm.formType == 3">
<div
v-for="(checkItme, checkIndex) in dynamicForm.checkedArr"
:key="checkIndex"
>
<el-form-item
:prop="`checkedArr.${checkIndex}.label`"
:rules="[
{ required: true, message: '请输入label', trigger: 'blur' },
{
pattern: /^[\u4e00-\u9fa5]+(·[\u4e00-\u9fa5]+)*$/,
message: '只允许输入汉字',
trigger: ['blur', 'change'],
},
]"
>
<span slot="label">{{ "复选框选项" + (checkIndex + 1) }}</span>
<el-input
v-model.trim="dynamicForm.checkedArr[checkIndex].label"
@blur="checkBlur($event)"
>
<el-button
v-if="checkIndex == 0"
slot="append"
icon="el-icon-plus"
@click.native="addRadioItem('checked')"
></el-button>
<el-button
v-if="checkIndex != 0 && checkIndex != 1"
slot="append"
icon="el-icon-minus"
@click.native="removeRadioItem(checkIndex, 'checked')"
></el-button>
</el-input>
</el-form-item>
</div>
</div>
<el-form-item label="该字段是否必填" prop="required">
<el-radio-group v-model="dynamicForm.required">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<el-button type="primary" @click="confirmBtn">确认添加</el-button>
</div>
<div class="right" v-if="toItemArr.length > 0">
<el-form
:model="toForm"
label-width="200px"
ref="toForm"
:rules="toFormRules"
>
<el-form-item
v-for="(formItem, formIndex) in toItemArr"
ref="itemUpload"
:key="formIndex"
:label="formItem.name"
:prop="formItem.key"
:rules="
formItem.required == 1
? [
{
required: true,
message: `请${
formItem.formType == '2' || formItem.formType == '6' || formItem.formType == '7'
? '选择'
: formItem.formType == '4'
? '上传'
: formItem.formType == '3'
? '至少选择一个'
: '输入'
}${formItem.formType == '4' ? '文件' : formItem.name}`,
trigger: 'blur',
},
]
: []
"
>
<el-input
v-model="toForm[formItem.key]"
v-if="formItem.formType == 1"
/>
<el-radio-group
v-model="toForm[formItem.key]"
v-if="formItem.formType == 2"
@change="noValid"
>
<el-radio
v-for="(radioItem, radioIndex) in formItem.radioArr"
:key="radioIndex"
:label="radioItem.keyRadio"
>{{ radioItem.value }}</el-radio
>
</el-radio-group>
<el-checkbox-group
v-model="toForm[formItem.key]"
v-if="formItem.formType == 3"
@change="noValid"
>
<el-checkbox
v-for="(checkItem, checkIndex) in formItem.checkedArr"
:key="checkIndex"
:label="checkItem.label"
></el-checkbox>
</el-checkbox-group>
<el-upload
v-if="formItem.formType == 4"
action="https://jsonplaceholder.typicode.com/posts/"
multiple
:limit="3"
:on-exceed="handleExceed"
:on-change="
(file, fileList) => {
uploadChange(file, fileList, formItem.key);
}
"
v-model="toForm[formItem.key]"
>
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
<el-input
type="textarea"
v-model="toForm[formItem.key]"
v-if="formItem.formType == 5"
/>
<el-select
v-model="toForm[formItem.key]"
:placeholder="`请选择${formItem.name}`"
v-if="formItem.formType == 6"
@change="noValid"
clearable
>
<el-option
v-for="(selectItmes, slectIndexs) in formItem.selectArr"
:key="slectIndexs"
:label="selectItmes.selectValue"
:value="selectItmes.keySelect"
>
</el-option>
</el-select>
<el-date-picker v-model="toForm[formItem.key]" type="date" placeholder="选择日期" v-if="formItem.formType == 7" value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-form>
<el-button
type="primary"
@click="submitServe"
v-if="JSON.stringify(toForm) != '{}'"
>提交到服务器</el-button
>
</div>
</div>
</template>
<script>
export default {
data() {
return {
//单选按钮的类型可以直接在此处添加
radioArray:[{label:'正常的input框',value:1},{label:'单选按钮',value:2},{label:'多选check',value:3},{label:'文件类型',value:4},{label:'textarea类型',value:5},{label:'select选择器类型',value:6},{label:'时间格式类型',value:7}],
repeat: false,
//新生成的表单信息 里面的字段都是动态添加
toForm: {},
//新生成表单信息的校验规则 里面的校验也是动态添加
toFormRules: {},
toItemArr: [],
dynamicForm: {
formType: 1, //表单类型 1代表正常的input 2代表单选按钮 3代表check复选框 4代表文件类型 5代表textarea类型 6代表select选择器类型 7代表时间格式类型
key: "", //表单中的每一项绑定的值(prop)
name: "", //表单中每一项的label
radioArr: [
{ keyRadio: "", value: "" },
{ keyRadio: "", value: "" },
],
checkedArr: [{ label: "" }, { label: "" }],
required: 1,
selectArr: [
{ keySelect: "", selectValue: "" },
{ keySelect: "", selectValue: "" },
],
},
dynamicFormRules: {
key: [
{ required: true, message: "请输入key", trigger: "blur" },
{
pattern: /^[A-Za-z-]+$/,
message: "只允许输入英文字母",
trigger: ["blur", "change"],
},
],
name: [
{ required: true, message: "请输入name", trigger: "blur" },
{
pattern: /^[\u4e00-\u9fa5]+(·[\u4e00-\u9fa5]+)*$/,
message: "只允许输入汉字",
trigger: ["blur", "change"],
},
],
},
};
},
methods: {
noValid() {
this.$refs["itemUpload"][0].clearValidate();
},
uploadChange(file, fileList, key) {
//清除校验
this.$refs["itemUpload"][0].clearValidate();
this.toForm[key] = fileList;
// console.log(this.toForm,fileList,this.toItemArr)
},
checkBlur(e) {
let sameArr = this.dynamicForm.checkedArr.filter((item, index) => {
return item.label == e.target.value;
});
// console.log(sameArr)
if (sameArr.length > 1 && e.target.value != "") {
this.$message.error("该字段已存在,请重新输入");
e.target.value = "";
}
},
//创建表单元素单选按钮时 ,不能够输入相同的key
radioKeyBlur(e, type) {
let sameArr = this.dynamicForm.radioArr.filter((item, index) => {
if (type == "key") {
return item.keyRadio == e.target.value;
} else if (type == "value") {
return item.value == e.target.value;
}
});
// console.log(sameArr)
if (sameArr.length > 1 && e.target.value != "") {
this.$message.error("该字段已存在,请重新输入");
e.target.value = "";
}
},
//创建表单元素select选择器时 ,不能够输入相同的key
selectKeyBlur(e, type) {
let sameArr = this.dynamicForm.selectArr.filter((item, index) => {
if (type == "key") {
return item.keySelect == e.target.value;
} else if (type == "value") {
return item.selectValue == e.target.value;
}
});
// console.log(sameArr)
if (sameArr.length > 1 && e.target.value != "") {
this.$message.error("该字段已存在,请重新输入");
e.target.value = "";
}
},
//切换单选按钮清空数据以及清除校验
radioChange() {
this.$refs.dynamicForm.resetFields();
},
keyInputBlur(e) {
// console.log(e.target.value)
let ev = e.target.value;
this.toItemArr.forEach((item, index) => {
if (ev == item.key || ev == item.name) {
this.$message.error("该字段已存在,请重新输入");
e.target.value = "";
this.repeat = true; //防止直接点击‘确认添加’按钮
}
return;
});
},
//上传文件超出规定大小回调函数
handleExceed() {},
//提交到服务器按钮
submitServe() {
this.$refs.toForm.validate((valid) => {
if (valid) {
this.toItemArr.forEach((item, index) => {
Object.keys(this.toForm).forEach((objItme, objIndex) => {
if (objItme == item.key) {
item.value = this.toForm[objItme];
}
});
});
console.log(this.toItemArr);
} else {
return false;
}
});
},
//确认按钮
confirmBtn() {
this.$refs.dynamicForm.validate((valid) => {
//通过校验
if (valid) {
//判断是否有重复定义的el-form-item
if (!this.repeat) {
if (this.dynamicForm.formType == 3) {
// this.toForm[this.dynamicForm.key] = []; 注释掉的这部分有问题需要用$set的方式动态添加属性
this.$set(this.toForm, this.dynamicForm.key, []);
} else {
this.$set(this.toForm, this.dynamicForm.key, "");
}
this.toItemArr.push(this.dynamicForm);
console.log(this.toItemArr);
this.dynamicForm = {
formType: 1, //表单类型 1代表正常的input 2代表单选按钮 3代表check复选框 4代表文件类型 5代表textarea类型
key: "", //表单中的每一项绑定的值(prop)
name: "", //表单中每一项的label
radioArr: [
{ keyRadio: "", value: "" },
{ keyRadio: "", value: "" },
],
checkedArr: [{ label: "" }, { label: "" }],
required: 1,
selectArr: [
{ keySelect: "", selectValue: "" },
{ keySelect: "", selectValue: "" },
],
};
} else {
this.repeat = false;
}
} else {
return false;
}
});
},
//添加radio的一项方法
addRadioItem(type) {
if (type == "radio") {
this.dynamicForm.radioArr.push({ radioArr: "", value: "" });
} else if (type == "checked") {
this.dynamicForm.checkedArr.push({ label: "" });
} else if (type == "select") {
this.dynamicForm.selectArr.push({ keySelect: "", selectValue: "" });
}
},
//删除radio其中一项的方法
removeRadioItem(index, type) {
if (type == "radio") {
this.dynamicForm.radioArr.splice(index, 1);
} else if (type == "checked") {
this.dynamicForm.checkedArr.splice(index, 1);
} else if (type == "select") {
this.dynamicForm.selectArr.splice(index, 1);
}
},
},
};
</script>
<style lang="less" scoped>
.left {
// float: left;
// width: 50%;
flex: 1;
width: 700px;
}
.right {
// float: right;
// // margin-left: 100px;
// margin-top: 9px;
// width: 50%;
flex: 1;
width: 700px;
}
.dynamic{
display: flex;
}
</style>
动态生成表单(添加select选择器类型和时间类型)
最新推荐文章于 2023-07-06 18:01:46 发布