美文网首页
动态form组件

动态form组件

作者: 幻影翔 | 来源:发表于2020-01-02 23:47 被阅读0次

通过数据渲染出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>

相关文章

网友评论

      本文标题:动态form组件

      本文链接:https://www.haomeiwen.com/subject/ylpaoctx.html