最近在公司的代碼中遇到的一些坑,目前公司代碼質量有點蛇皮..(組件套組件被套用的組件只是一個表單,翻來翻去就為了看個破錶單...)雖然不是我寫的,但是在維護上確實有點麻煩... 索性直接用jsx抽個表單.
依賴:
"@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
"@vue/babel-preset-jsx": "^1.4.0",
"element-ui": "^2.15.13",
"vue": "^2.6.14"
練習項目圖省事直接用的cli
廢話不多説直接上代碼:
傳入對象: dataObj dataObj2 是一樣的 我把這兩個組件都引到了同一個頁面去測試,省事
dataObj2: {
type: "add",// info
list: [
{
label: "input框",
prop: "name",
type: "input",
value: "123",
disabled: false,
attrs: {
placeholder: "請輸入name",
onInput:(e)=>{
console.log('%c [ arrts裏面的input ]-', 'font-size:13px; background:pink; color:#bf2c9f;', e)
}
},
event: {
input: (e) => {
console.log(
"%c [ onInput input dataObj2]-",
"font-size:13px; background:skyblue; color:#bf2c9f;",
e
);
},
onInput: (e) => {
console.log(
"%c [ onInput input dataObj222]-",
"font-size:13px; background:skyblue; color:#bf2c9f;",
e
);
},
onChange: (e) => {
console.log(
"%c [ onChange change dataObj2]-",
"font-size:13px; background:skyblue; color:#bf2c9f;",
e
);
},
},
},
{
label: "select框",
prop: "desc",
type: "select",
value: "",
option: [
{ label: "活動一", value: "huodong1" },
{ label: "活動二", value: "huodong2" },
],
},
{
label: "radio單選框",
prop: "radio",
type: "radio",
value: "",
option: [
{ label: "單選框一", value: "radio1" },
{ label: "單選框二", value: "radio2" },
],
},
{
label: "input框2",
prop: "name2",
type: "input",
value: "",
disabled: false,
attrs: {
placeholder: "請輸入name2",
},
event: {
input: (e) => {
console.log(
"%c [ e input ]-",
"font-size:13px; background:skyblue; color:#bf2c9f;",
e
);
},
change: (e) => {
console.log(
"%c [ e change ]-",
"font-size:13px; background:skyblue; color:#bf2c9f;",
e
);
},
},
},
],
rules: {
name: [
{ required: true, message: "請輸入活動名稱", trigger: "blur" },
],
desc: [
{ required: true, message: "請輸入活動形式", trigger: "blur" },
],
name2: [
{ required: true, message: "請輸入活動名稱2", trigger: "blur" },
],
},
labelWidth: "100px",
}
jsx版:
結構
<div class="form-box">
<helloJsx :datas="dataObj2" @saveSubmit="submit2"></helloJsx>
</div>
組件代碼:
<script>
export default {
props: ["datas"],
data() {
return {
form: {},
};
},
methods: {
html() {
return (
<div>
{this.datas.refFormName}
<el-form
label-width={this.datas.labelWidth}
ref="onlyForm"
class="class-form"
rules={this.datas.rules}
props={{ model: this.form }}
>
{this.datas.list.map((e) => (
<el-form-item label={e.label} prop={e.prop}>
{e.type === "input" ? (
<el-input
v-model={this.form[e.prop]}
{...{ on: { ...e.event } }}
{...{ attrs: e.attrs }}
disabled={
e.disabled
? e.disabled
: this.datas.type === "info"
? true
: false
}
></el-input>
) : (
""
)}
{e.type === "select" ? (
<el-select
v-model={this.form[e.prop]}
{...{ on: { ...e.event } }}
{...{ attrs: e.attrs }}
disabled={
e.disabled
? e.disabled
: this.datas.type === "info"
? true
: false
}
>
{e.option.map((s) => {
return (
<el-option label={s.label} value={s.value}></el-option>
);
})}
</el-select>
) : (
""
)}
{e.type === "radio" ? (
<el-radio-group
v-model={this.form[e.prop]}
disabled={
e.disabled
? e.disabled
: this.datas.type === "info"
? true
: false
}
{...{ on: { ...e.event } }}
{...{ attrs: e.attrs }}
>
{e.option.map((e) => {
return (
<el-radio label={e.value}>{e.label}</el-radio>
);
})}
</el-radio-group>
) : (
""
)}
</el-form-item>
))}
{this.datas.type !== "info" ? (
<el-form-item>
<el-button type="primary" onClick={this.submitForm}>
立即創建
</el-button>
<el-button onClick={this.resetForm}>重置</el-button>
</el-form-item>
) : (
""
)}
</el-form>
</div>
);
},
submitForm() {
this.$refs["onlyForm"].validate((valid) => {
if (valid) {
console.log(
"%c [ data-submit2 ]-",
"font-size:13px; background:skyblue; color:#bf2c9f;",
2222
);
this.$emit("saveSubmit", this.form);
} else {
console.log("error222 submit!!");
return false;
}
});
},
resetForm() {
this.$refs["onlyForm"].resetFields();
},
},
render() {
return this.html();
},
};
</script>
<style scoped>
.class-form {
width: 300px;
}
</style>
組件複用版:
結構
<h3>循環配置項</h3>
<div class="form-box">
<myForm :datas="dataObj" @submit="submit" @back="back"></myForm>
</div>
組件代碼:
<template>
<div>
<el-form
:label-width="datas.labelWidth"
:ref="datas.refFormName"
class="class-form"
:rules="datas.rules"
:model="form"
>
<el-form-item
:label="item.label"
:prop="item.prop"
v-for="(item, index) in datas.list"
:key="index"
>
<el-input
v-if="item.type === 'input'"
v-model="form[item.prop]"
:disabled="
item.disabled ? item.disabled : datas.type === 'info' ? true : false
"
v-bind="{ ...item.attrs }"
v-on="{ ...item.event }"
></el-input>
<el-select
v-if="item.type === 'select'"
v-model="form[item.prop]"
:placeholder="'請選擇' + item.label"
:disabled="
item.disabled ? item.disabled : datas.type === 'info' ? true : false
"
>
<el-option
:label="i.label"
:value="i.value"
v-for="i in item.option"
:key="i.value"
></el-option>
</el-select>
<el-radio-group
v-if="item.type === 'radio'"
v-model="form[item.prop]"
:disabled="
item.disabled ? item.disabled : datas.type === 'info' ? true : false
"
>
<el-radio :label="i.value" v-for="i in item.option" :key="i.value">{{
i.label
}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="datas.type !== 'info'">
<el-button type="primary" @click="submitForm('ruleForm')"
>立即創建</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
<el-form-item v-else>
<el-button @click="back('ruleForm')">關閉</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "Demo02MyForm",
props: {
datas: {
type: Object,
require: true,
default: () => {
return {
type: "add", // add edit info
list: [],
rules: {},
labelWidth: "100px",
refFormName: "form",
};
},
},
},
data() {
return {
form: {},
};
},
mounted() {
this.initData();
},
methods: {
initData() {
const obj = {};
this.datas.list.forEach((e) => {
obj[e.prop] = obj[e.value] ? obj[e.value] : "";
});
this.form = obj;
if (this.datas.type !== "add") {
for (const key in this.form) {
this.datas.list.forEach((e) => {
if (e.prop === key) {
this.form[key] = e.value;
}
});
}
}
},
submitForm() {
this.$refs[this.datas.refFormName].validate((valid) => {
if (valid) {
this.$emit("submit", this.form);
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm() {
this.$refs[this.datas.refFormName].resetFields();
},
back() {
this.$emit("back", false);
},
},
};
</script>
<style scoped>
.class-form {
width: 300px;
}
</style>