组件化封装el-form
最近在写一个管理系统的项目,基本上每个页面都有el-form,代码写的多了就不想写了,想省事就得整它啊。
设计思想
表单的功能就是收集数据发送到后台,这就是它的使命。采用面向对象的设计思想,我想用你的组件我只管把你规定的数据格式传给你其它的我不管,至于你怎么绑值,和发送请求的,我不需要知道,我只要结果!
开整
<template>
<el-form
ref="ruleForm"
class="demo-ruleForm"
:model="form"
:label-width="formData.labelWidth"
:inline="formData.inline"
:rules="formData.rules"
:size="formData.size"
:label-position="formData.labelPosition"
>
<el-form-item
v-for="(item, index) in formData.formItem"
:key="index"
:label="item.label"
:prop="item.prop"
>
<!-- 文本框 -->
<el-input
v-if="item.type === 'text'"
v-model="form[item.prop]"
:disabled="item.isDisabled"
/>
<!-- 密码框 -->
<el-input
v-if="item.type === 'password'"
v-model="form[item.prop]"
type="password"
:disabled="item.isDisabled"
/>
<!-- 单选框 -->
<el-radio-group
v-if="item.type==='radio'"
v-model="form[item.prop]"
>
<el-radio
v-for="item in item.options"
:key="item.value"
:label="item.value"
>
{{ item.name }}
</el-radio>
</el-radio-group>
<!-- 单选按钮 -->
<el-radio-group
v-if="item.type==='radioButton'"
v-model="form[item.prop]"
:disabled="item.isDisabled"
>
<el-radio-button
v-for="item in item.options"
:key="item.value"
:label="item.value"
>
{{ item.name }}
</el-radio-button>
</el-radio-group>
<!-- 多选框组 -->
<el-checkbox-group
v-if="item.type==='checkbox'"
v-model="form[item.prop]"
>
<el-checkbox
v-for="item in item.options"
:key="item.value"
:disabled="item.isDisabled"
:label="item.value"
>
{{item.name}}
</el-checkbox>
</el-checkbox-group>
<!-- 下拉框 -->
<el-select
v-if="item.type==='select'"
v-model="form[item.prop]"
:multiple="item.multiple"
collapse-tags
clearable
:disabled="item.isDisabled"
:placeholder="item.placeholder"
>
<el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.isDisabled"
/>
</el-select>
<!-- 联级面板 -->
<el-cascader
v-if="item.type==='cascader'"
v-model="form[item.prop]"
:options="item.options"
:props="item.isMore"
clearable
/>
<!-- 开关 -->
<el-switch
v-if="item.type==='switch'"
v-model="form[item.prop]"
/>
<!-- 日期选择器 -->
<el-date-picker
v-if="item.type==='date'"
v-model="form[item.prop]"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
/>
<!-- 时间选择器 -->
<el-time-picker
v-if="item.type==='time'"
v-model="form[item.prop]"
placeholder="请选择时间"
/>
<!-- 日期时间选择器 -->
<el-date-picker
v-if="item.type==='dateTime'"
v-model="form[item.prop]"
type="datetime"
placeholder="选择日期时间"
/>
<!-- 日期和时间范围选择器 -->
<el-date-picker
v-if="item.type==='datetimerange'"
v-model="form[item.prop]"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit('ruleForm')"
>
保存
</el-button>
<el-button
@click="resetForm('ruleForm')"
>
重置
</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
formData: {
type: Object,
required: true
}
},
data() {
return {
form: {}
};
},
created() {
this.bindValue();
},
methods: {
onSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
console.log(this.form);
alert('发送请求去');
} else {
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
bindValue() {
const obj = {};
this.formData.formItem.forEach((item, index) => {
// 这里不能写成this.form = obj 因为传递的不是值,而是引用,他们指向了同一个空间!
obj[item.prop] = item.value;
});
this.form = {...obj};
}
}
};
</script>
<style scoped>
</style>
在页面中引入组件
<template>
<div>
<form-icon :form-data="formData" />
</div>
</template>
<script>
import formIcon from '@/components/ObjectForm';
export default {
components: {
formIcon
},
data() {
return {
formData: {
rules: {
userName: [
{required: true, message: '请输入用户名', trigger: 'blur'}
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'}
]
},
labelWidth: '100px',
inline: false,
labelPosition: 'right',
size: 'small',
formItem: [
{type: 'text', label: '用户名', isDisabled: false, placeholder: '请输入用户名', prop: 'userName', value: '6666', required: true},
{type: 'password', label: '密码', isDisabled: false, placeholder: '请输入密码', prop: 'password', value: '', required: true},
{type: 'radio', label: '性别', isDisabled: false, prop: 'sex', value: '', options: [{name: '男', value: '1'}, {name: '女', value: '0'}]},
{type: 'switch', label: '状态', isDisabled: false, prop: 'status', value: '0'},
{
type: 'radioButton',
isDisabled: true,
label: '选择城市',
prop: 'city',
value: 'huaian',
options: [
{name: '上海', value: 'shanghai'},
{name: '北京', value: 'beijing'},
{name: '淮安', value: 'huaian'}
]
},
{
type: 'checkbox',
isDisabled: false,
label: '爱好',
prop: 'hoppies',
value: [],
options: [
{name: '游戏', value: 'LOL', isDisabled: true},
{name: '健身', value: 'fitness', isDisabled: false},
{name: '娱乐', value: 'bath', isDisabled: false},
{name: 'Code', value: 'code', isDisabled: true}
]
},
{
type: 'select',
isDisabled: false,
// 是否开启多选
multiple: false,
label: '选择语言',
prop: 'languages',
value: [],
options: [
{name: 'JavaScript', value: 'JavaScript', isDisabled: true},
{name: 'Java', value: 'Java', isDisabled: false},
{name: 'Python', value: 'Python', isDisabled: false},
{name: 'C#', value: 'C#', isDisabled: false},
{name: 'C', value: 'C', isDisabled: false},
{name: 'Go', value: 'Go', isDisabled: false},
{name: 'PHP', value: 'PHP', isDisabled: false}
]
},
{
type: 'cascader',
label: '地址',
prop: 'dizhi',
isMore: {multiple: false},
isDisabled: false,
value: [],
options: [
{
value: 'js',
label: '江苏省',
children: [
{
value: 'nanjing',
label: '南京市'
},
{
value: 'suzhou',
label: '苏州市'
},
{
value: 'wuxi',
label: '无锡市'
},
{
value: 'huaian',
label: '淮安市',
children: [
{
value: 'pjpq',
label: '清江浦区'
},
{
value: 'hyq',
label: '淮阴区'
}
]
}
]
},
{
value: 'sh',
label: '上海市',
children: [
{
value: 'pudong',
label: '浦东新区'
},
{
value: 'xuhui',
label: '徐汇区'
},
{
value: 'minhang',
label: '闵行区'
},
{
value: 'songjiang',
label: '松江区',
children: [
{
value: 'dongjing',
label: '洞泾'
},
{
value: 'jiuting',
label: '九亭'
}
]
}
]
}
]
},
{type: 'date', label: '日期', prop: 'starTime', value: ''},
{type: 'time', label: '时间', prop: 'time', value: ''},
{type: 'dateTime', label: '日期时间', prop: 'dateTime', value: ''},
{type: 'datetimerange', label: '范围选择器', prop: 'datetimerange', value: ''}
]
}
};
}
};
</script>
<style lang="scss" scoped>
</style>
到这里对el-form简单封装完成了,基本能够满足需求!满足不了继续往里头加就完事了。
思考
- 数据联动的时候数据量过大怎么搞?
第一层数据可以给过来,然后给点击事件再去返回结果 - 上传文件、图片、视频怎么搞?
Element el-upload上传
网友评论