美文网首页
动态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