封装效果通过数据渲染出form组件
封装组件 from-group.vue
<template>
<Form ref="form"
v-if="Object.keys(valueList).length"
:label-width="labelWidth"
:model="valueList"
:rules="rules">
<FormItem
v-for="(item, index) in list"
:label="item.label"
label-position="left"
:prop="item.name"
:error="errorStore[item.name]"
:key="`${_uid}_${index}`"
@click.native="handleFocus[item.name]"
>
<component :is="item.type"
:range="item.range"
:placeholder="item.placeholder"
:icon="item.icon"
v-model="valueList[item.name]">
<template v-if="item.children">
<component
v-for="(child, i) in item.children.list"
:is="item.children.type"
:key="`${_uid}_${index}_${i}`"
:label="child.label"
:value="child.value">{{ child.title }}</component>
</template>
</component>
</FormItem>
<FormItem>
<Button @click="handleSubmit" type="primary">提交</Button>
<Button @click="handleReset">重置</Button>
</FormItem>
</Form>
</template>
<script>
import { sendFormData } from "@/api/data";
import clonedeep from 'clonedeep'
export default {
name: "FormGroup",
data () {
return {
initValueList: [], //初始化数据
rules: {},
valueList: {}, // form填的值
errorStore: {} // 校验的错误对象
}
},
props: {
list: {
type: Array,
default: () => []
},
labelWidth: {
type: Number,
default: 100
},
url: {
type: String,
required: true
}
},
watch: {
// 监听list变化
list () {
this.setInitValue();
}
},
methods: {
setInitValue () {
let rules = {};
let valueList = {};
let initValueList = {};
let errorStore = {};
this.list.forEach(item => {
rules[item.name] = item.rule;
valueList[item.name] = item.value;
initValueList[item.name] = item.value;
errorStore[item.name] = '';
})
this.rules = rules;
this.valueList = valueList;
this.initValueList = initValueList;
this.errorStore = errorStore
},
handleSubmit () {
// 表单校验
this.$refs.form.validate(valid => {
if (valid) {
sendFormData({
url: this.url,
data: this.valueList
}).then(res => {
this.$emit('on-submit-success',res);
}).catch(err => {
this.$emit('on-submit-error',err);
for (let key in err ) {
this.errorStore[key] = err[key];
}
})
}
})
},
handleReset () {
this.valueList = clonedeep(this.initValueList);
},
handleFocus (name) {
this.errorStore[name] = '';
}
},
mounted () {
this.setInitValue();
}
}
</script>
<style scoped>
</style>
api中的 sendFormData方法
export const sendFormData = ({ url, data }) => {
return axios.request({
url: url,
data: qs.stringify({formData: JSON.stringify(data)}),
method: 'post'
})
};
视图 form.vue
<template>
<div class="form-wrapper">
<form-group :list="formList" :url="url"> </form-group>
</div>
</template>
<script>
import FormGroup from "_c/form-group/form-group";
export default {
components: {
FormGroup
},
data () {
return {
url: '/api/file/user/setFormData',
// 生成组件的数据
formList: [
{
name: 'name',
type: 'i-input',
value: '',
label: '姓名',
rule: [
{ required: true, message: 'The name cannot be empty', trigger: 'blur' }
]
},
{
name: 'range',
type: 'slider',
value: [ 10, 40],
range: true,
label: '范围'
},
{
name: 'sex',
type: 'i-select',
value: '',
label: '性别',
children: {
type: 'i-option',
list: [
{ value: 'woman', title: '女'},
{ value: 'man', title: '男'},
]
}
},
{
name: 'education',
type: 'radio-group',
value: 1,
label: '学历',
children: {
type: 'radio',
list: [
{ label: 1, title: '本科'},
{ label: 2, title: '研究生'},
{ label: 3, title: '博士'},
]
}
},
{
name: 'skill',
type: 'checkbox-group',
value: [],
label: '技能',
children: {
type: 'checkbox',
list: [
{ label: 1, title: 'Vue'},
{ label: 2, title: 'NodeJs'},
{ label: 3, title: 'Mysql'},
]
}
},
{
name: 'is-work',
type: 'i-switch',
value: true,
label: '是否在职'
},
{
name: 'start-time',
type: 'date-picker',
value: '',
placeholder:'请选择时间',
label: '开始时间'
},
{
name: 'submit',
type: 'i-button',
value: '',
icon: 'logo-facebook',
label: '提交'
}
]
}
},
methods: {
//
}
}
</script>
<style lang="less">
.form-wrapper{
padding: 20px;
}
</style>
网友评论