基于vue,element-Ui动态表单的实现过程

220 阅读3分钟
export default {
data() {
return {
chooseModule: "0",
checkBoxOptions: [
{
value: "0",
label: "自定义选项",
},
{
value: "1",
label: "引用字典",
},
],
contentTypeList: [
{
label: "任意文字",
value: "0",
},
{
label: "手机号",
value: "1",
},
{
label: "固定电话",
value: "2",
},
{
label: "电子邮箱地址",
value: "3",
},
{
label: "身份证号码",
value: "4",
},
{
label: "企业信用代码",
value: "5",
},
],
tableOneList: [],
saveState: false,
queryParams: {
name: "",
code: "",
dataGroup: "",
dataLength: 10,
description: "",
dataType: "0",
contentType: "0",
dataMax: 0,
dataMin: 0,
dataPercision: 0,
gridColumns: 5,
dataIsNull: "1",
defaultValue: "",
defaultValueNum: false,
customOption: [],
},
rules: {
name: [
{ required: true, message: "字段名称不能为空", trigger: "blur" },
],
code: [{ required: true, message: "编码不能为空", trigger: "blur" }],
},
};
},
props: {
parentId: "",
classId: "",
},
methods: {
deleteRow(i) {
this.tableOneList.splice(i, 1);
},
confirmEdit(row) {
if (!row.dataShow || !row.dataReserve) {
this.$message({
message: "请填入相应的值",
type: "error",
});
return;
}
row.edit = false;
row.disabled = false;
},
addRow() {
let newLine = {
dataShow: "",
dataReserve: "",
edit: true, // 新增时处于可编辑状态,所以按钮是保存和取消
disabled: true, // 打开编辑状态
};
this.tableOneList.push(newLine); // 移到最后一行
},
startEdit(row) {
row.edit = !row.edit;
row.disabled = true;
},
handleConfig() {},
accountInput(val) {
let codeReg = new RegExp("[A-Za-z0-9]+"), //正则 英文+数字;
len = val.length,
str = "";
for (var i = 0; i < len; i++) {
if (codeReg.test(val[i])) {
str += val[i];
}
}
this.queryParams.code = str;
},
init(id) {
const _this = this;
axios.get("/dynamicMetadataAttribute/getById/" + id).then((resp) => {
if (resp.data) {
_this.queryParams = resp.data;
if (_this.queryParams.customOption) {
_this.tableOneList = JSON.parse(_this.queryParams.customOption);
} else {
_this.tableOneList = [];
}
}
});
},
save(queryParams) {
this.saveState = true;
const _this = this;
this.queryParams.customOption = JSON.stringify(this.tableOneList);
this.queryParams.classId = this.classId;
this.$refs[queryParams].validate((valid) => {
if (valid) {
axios
.post("/dynamicMetadataAttribute/saveOrUpdate", _this.queryParams)
.then(function (resp) {
if (resp.data) {
_this.$message({
showClose: true,
type: "success",
message: "保存成功",
});
_this.$emit("closedialogAdd");
} else {
_this.saveState = false;
}
});
} else {
this.saveState = false;
return false;
}
});
},
closeBtn() {
this.$emit("closedialogAdd");
},
},
created() {
if (this.parentId) this.init(this.parentId);
},
};
</div>

<--------------------------------------------------------------------------------------->

上面的代码是新增表单配置项的所有代码,保存至后台。这里保存的数据为表单的配置项,下面的表单渲染组件需要传递的数据就是从这来的。。。。

<--------------------------------------------------------------------------------------------->

name: "dynamicForm",
props: {
fieldMap: {
//提交的数据
type: Object,
default: () => {
return {};
},
},
formData: {
//提交的数据
type: Object,
default: () => {
return {};
},
},
disabled: {
type: Boolean,
default: false,
},
inline: {
type: Boolean,
default: true,
},
},
data() {
return {
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
watch: {
fieldMap(newvalue, oldvalue) {
for (const key in newvalue) {
newvalue[key].forEach((item) => {
if (item.dataType == "3" || item.dataType == "7") {
this.$set(this.formData, item.code, []);
} else {
this.$set(this.formData, item.code, "");
}
});
}
},
immediate: true,
},
methods: {
topRow(index, item) {
//行上移
let updata = this.formData[item][index - 1];
this.formData[item].splice(index - 1, 1);
this.formData[item].splice(index, 0, updata);
},
buttomRow(index, item) {
//行下移
let updata = this.formData[item][index + 1];
this.formData[item].splice(index + 1, 1);
this.formData[item].splice(index, 0, updata);
},
deleteRow(index, item) {
this.formData[item].splice(index, 1);
},
addRow(table) {
let newLine = {};
table.push(newLine);
},
deletAllRow(item) {
this.formData[item] = [];
},
inputNumber(value, items) {
if (value.indexOf(".") > 0) {
if (items.dataPercision > 0) {
this.$nextTick(() => {
this.formData[items.code] = value.substring(
0,
value.indexOf(".") + items.dataPercision + 1
);
});
} else {
this.$nextTick(() => {
this.formData[items.code] = value.substring(
0,
value.indexOf(".") + items.dataPercision
);
});
}
}
},
checktextNumberInput(value, item) {
if (value < item.dataMin) {
this.$message({
showClose: true,
type: "error",
message: item.name + "不能小于最小值" + item.dataMin,
});
}
if (value > item.dataMax) {
this.$message({
showClose: true,
type: "error",
message: item.name + "不能大于最大值" + item.dataMax,
});
}
},
checktextInput(item) {
if (item.dataIsNull == "0") {
if (this.formData[item.code] == "") {
this.$message({
showClose: true,
type: "error",
message: item.name + "是必填项",
});
}
}
if (item.contentType == "1") {
let resp = /^1[3-8][0-9]\d{8}$/;
if (!resp.test(this.formData[item.code])) {
this.$message({
showClose: true,
type: "error",
message: "请输入正确手机号",
});
}
}
if (item.contentType == "2") {
let resp = /((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)/;
if (!resp.test(this.formData[item.code])) {
this.$message({
showClose: true,
type: "error",
message: "请输入正确固定电话号",
});
}
}
if (item.contentType == "3") {
let resp = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
if (!resp.test(this.formData[item.code])) {
this.$message({
showClose: true,
type: "error",
message: "请输入正确电子邮箱地址",
});
}
}
if (item.contentType == "4") {
let resp = /^(\d{6})(\d{4}|\d{2})(\d{2})(\d{2})(\d{3})([0-9]|X)*$/;
if (!resp.test(this.formData[item.code])) {
this.$message({
showClose: true,
type: "error",
message: "请输入正确身份证号",
});
}
}
if (item.contentType == "5") {
let resp = /^[a-zA-Z]{2}\d{6}[a-zA-Z]{10}$/;
if (!resp.test(this.formData[item.code])) {
this.$message({
showClose: true,
type: "error",
message: "请输入正确企业信用号",
});
}
}
},
checktextareaInput(item) {
if (item.dataIsNull == "0") {
if (this.formData[item.code] == "") {
this.$message({
showClose: true,
type: "error",
message: item.name + "是必填项",
});
}
}
},
},
};
</div> .boxs {
border: 1px solid #ded9d9;
padding: 10px;
margin: 10px;
}

上面代码,就是动态表单的渲染的代码, 已封装成组件,自己用的话,写个组件,把上面的代码丢进去就可以用了。有所瑕疵,还望各路大神多多指教,

这里贴图为组件的用法,fieldMap为动态配置表单的数据,formData为整个表单提交至后台的数据。

下面让大家看看效果:

(动态表单的新增配置项弹窗)

(动态表单渲染的效果)

嗯,就是这样,这些是前端部分,下一篇文章我会附上后端代