Vue 项目封装表单类型组件(ElementUi)

Vue 项目封装表单类型组件 iform.vue

当我们在做Vue项目时,有时候项目很大,页面功能比较多时,很多控件堆在一起,很是臃肿,管理起来很麻烦。因此,我们就需要封装一些组件,达到简洁高效、可复用的效果。本章节主要是介绍如何封装表单类型的组件。

封装表单类型组件需要用到的文件以及其他组件(重要)

1、i-input.vue 公用组件,是i-form组件的最重要的组件,主要封装的就是这个,i-form就是将i-input组件套了一层外壳(el-form)。因此,总的来说,是我们这章节主要封装的对象。

2、publicform.js 文件,这个文件就是一些封装组件的方法,文件里面定义了几种表单类型(input、select、selects、date、time、combogrid、combopanel、switch、input_number、input_numbers)。

3、myPublicForm i-input封装组件里面注册的子组件,是需要渲染的基础表单子组件,因为当我们publicform.js 文件返回给组件的是一大串html的字符串,如果直接使用 html属性渲染 那一大串html字符串时,是渲染不出来的,为什么呢?因为我这里vue项目使用了ElementUi框架,直接使用 html属性渲染是渲染不出来Elementui的各种标签的。因此,我们需要使用注册的子组件来渲染Elementui字符串。

一、publicform.js 文件的实现

// 封装基础组件框架
const getBaseElem = function(elem, opt) {
    let baseOptions = {
        type: '',
        model: '',
        placeholder: '',
        value: ''
    };
    var publicFrom = {
        input: function (attr) {
            if (attr) {
                let elemetOptions = getElement(attr);
                if (elemetOptions) {
                    var input = '<el-input' + elemetOptions + '></el-input>';
                    return input;
                } else {
                    return '<el-input></el-input>';
                }
            } else {
                
            }
        },
        select: function (attr, isMultiple) {
            if (!attr.option) {
                let elemetOptions = getElement(attr);
                if (elemetOptions) {
                    var select = '<el-select' + elemetOptions + '></el-select>';
                    return select;
                } else {
                    return '<el-select></el-select>';
                }
            } else {
                let elemetOptions = getElement(attr);
                if (elemetOptions) {
                    let multiple = isMultiple ? ' multiple ' : '';
                    var select = '<el-select' + elemetOptions + '' + multiple + '>';
                    attr.option.forEach(item => {
                        let elemetOptions = getElement(item);
                        select += '<el-option ' + elemetOptions + '></el-option>'
                    })
                    select += '</el-select>';
                    return select;
                } else {
                    return '<el-select></el-select>';
                }
            }
        },
        selects: function (attr) {
            return this.select(attr, true)
        },
        date: function (attr) {
            let elemetOptions = getElement(attr);
            if (elemetOptions) {
                var date = '<el-date-picker' + elemetOptions + '></el-date-picker>';
                return date;
            } else {
                return '<el-date-picker></el-date-picker>';
            }
        },
        time: function (attr) {
            let elemetOptions = getElement(attr);
            if (elemetOptions) {
                var time = '<el-time-picker' + elemetOptions + '></el-time-picker>';
                return time;
            } else {
                return '<el-time-picker></el-time-picker>';
            }
        },
        combogrid: function (attr) {
            if (attr) {
                let elemetOptions = JSON.stringify(attr);
                if (elemetOptions) {
                    var input = "<icombogrid ref='combogrid' :getOptions='"+elemetOptions+"'></icombogrid>";
                    return input;
                } else {
                    return '<icombogrid></icombogrid>';
                }
            } else {
                
            }
        },
        combopanel: function (attr) {
            if (attr) {
                let elemetOptions = JSON.stringify(attr);
                if (elemetOptions) {
                    var input = "<icombopanel :getOptions='"+elemetOptions+"'></icombopanel>";
                    return input;
                } else {
                    return '<icombopanel></icombopanel>';
                }
            } else {
                
            }
        },
        switch: function (attr) {
            let elemetOptions = getElement(attr);
            if (elemetOptions) {
                var time = '<el-switch' + elemetOptions + ' active-color="#13ce66"></el-switch>';
                return time;
            } else {
                return '<el-switch></el-switch>';
            }
        },
        input_number: function (attr) {
            let elemetOptions = getElement(attr);
            if (elemetOptions) {
                var time = '<el-input-number' + elemetOptions + ' controls-position="right"></el-input-number>';
                return time;
            } else {
                return '<el-input-number></el-input-number>';
            }
        },
        input_numbers: function (attr) {
            let array = {};
            let elemetOptions = getElement(attr);
            if (elemetOptions) {
                let time = '<div ' + elemetOptions + '>';
                attr.numbers.forEach((item) => {
                    array = Object.assign({}, array, item);
                    let arrayElem = getElement(array);
                    time += '<el-input-number' + arrayElem + ' controls-position="right"></el-input-number>';
                });
                time += '</div>'
                return time;
            } else {
                return '<el-input-number></el-input-number>';
            }
        }
    };
    return publicFrom[elem](opt)
},
// 解析对象键值对成属性
getElement = function (attr) {
    var v = 'v-',
        el = 'el-',
        typeV = ["model", "if", "show", "for"],
        elemHas = ["type", "model", "placeholder", "value", "style", "label", "name"]; // 通用属性
    if (attr) {
        var attrString = '',
            attrElement = '';
        for (var key in attr) {
            elemHas.forEach(item => {
                if (key == item) {
                    if (key == "model") {
                        attrString = v + key + '=' + '"' + attr[key] + '"';
                        attrString = attrString.toString()
                        attrElement += ' ' + attrString + ' ';
                    } else {
                        attrString = key + '=' + '"' + attr[key] + '"';
                        attrString = attrString.toString()
                        attrElement += ' ' + attrString + ' ';
                    }
                }
            })
        }
        return attrElement;
    } else {
        throw new Error("attr属性必须有值!");
    }
}
export default getBaseElem

二、i-input组件的实现

template 只需要一个子组件

<template>
    <div>
        <myPublicForm ref="myPublicForm"></myPublicForm>
    </div>
</template>

script 注册子组件,并且引入publicform文件,然后再渲染到子组件里。

<script>
import publicform from '../modules/publicForm.js' // 引入公共表单组件
import {EventBus} from '../modules/event-bus.js' // 引入事件总线
import Vue from 'vue';
export default {
    components: { // 需要渲染的基础表单子组件
        myPublicForm: {
            props: {
                showInputElem: {
                    type: String,
                    default: '<div></div>'
                },
                formData: {
                    type: Object,
                    default: () => {
                        return {}
                    }
                },
            },
            mounted() {
            },
            watch: {
            },
            render(h) { // -----------------------渲染--------最重要的部分---------
                const that = this
                const com = Vue.extend({
                    data() {
                        return {
                            rightFormData: that.newformData,
                        }
                    },
                    template: that.newShowInputElem,
                    mounted() {
                    	// 判断有没有combogrid的属性
                        this.$refs.hasOwnProperty("combogrid") && (that.combogrid = this.$refs.combogrid);
                    },
                });
                return h(com, {});
            },
            data() {
                return {
                    newShowInputElem: this.showInputElem,
                    newformData: this.formData,
                    combogrid:{}
                }
            }
        }
    },
    props: {
        formTypeValue: {
            type: Object,
            default: () => {
                return {}
            }
        },
        rightFormData: {
            type: Object,
            default: () => {
                return {}
            }
        }
    },
    watch: {
        rightFormData: {
            deep: true,
            handler (newValue) {
                // console.log('rightform', newValue)
                this.$refs.myPublicForm.newformData = this.rightFormData
            }
        }
    },
    data() {
        return {
        }
    },
    mounted() {
        this.getinputElem();
    },
    methods: {
        getinputElem() { // 渲染
            this.$refs.myPublicForm.newformData = this.rightFormData;
            if (this.formTypeValue.hasOwnProperty('elem')) {
                let arr = '';
                arr = publicform(this.formTypeValue.elem, this.formTypeValue);
                this.$refs.myPublicForm.newShowInputElem = arr;
            }
        },
        disappear() { // 清除
            this.$refs.myPublicForm.combogrid.hasOwnProperty("disappear") && this.$refs.myPublicForm.combogrid.disappear();
        }
    }
}
</script>

style

<style lang="scss">
    .el-table__row .el-input {
        width: 100%;
        .el-input__inner {
            height: 100%;
        }
    }

</style>

三、i-form组件的实现

i-form 组件就比较简单,主要的工作就是将 i-input 包上一层
< el-form>
< el-form-item>**************< /el-form-item>
</ el-form>

template

<template>
    <div :model="model" class="i-form">
        <el-form :inline="true" class="demo-form-inline">
            <el-form-item :label="item.label" v-for="(item, index) in formTypeValue" :key="index">
                <iinput  :ref="'input_'+index" :formTypeValue="item" :rightFormData="rightFormData"></iinput>
            </el-form-item>
        </el-form>
        <slot></slot>
    </div>
</template>

script

<script>
import publicform from '../modules/publicForm.js' // 引入公共表单组件
import {EventBus} from '../modules/event-bus.js' // 引入事件总线
import Iinput from '../allPage/i-input.vue';
import Vue from 'vue';
export default {
    name: 'i-form',
    components: {Iinput},
    props: {
        model: { // model
            type: Object,
            default: () => {
                return {}
            }
        },
        rightFormData: { // 父级传的或者自己默认的model值
            type: Object,
            default: () => {
                return {}
            }
        },
        formTypeValue: { // 父级传的或者自己默认的表单集合
            type: Array,
            default: () => {
                return []
            }
        },
        timeValue: {
            type: String,
            default: ''
        }
    },
    data() {
        return {
        }
    },
    watch: {
        rightFormData: {
            deep: true,
            handler(newValue) {
                console.log('form', newValue)
            }
        }
    },
    mounted() {
    },
    methods: {
        disappear() { // 清除
            this.formTypeValue.forEach((item,index) => {
                var key = `input_${index}`;
                this.$refs[key][0].disappear();
            });
        },
    }
}
</script>

style

<style lang="scss">
    .i-form {
        padding: 0 10px; 
        display: flex;
        align-items: center;
        .el-button {
            height: 30px;
        }
    }
    .el-input {
        width: 200px;
        height: 30px;
    }
    .el-form--inline .el-form-item {
        margin-right: 30px;
        margin-bottom: 0px;
    }
</style>

End ~

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue ElementUI提供了丰富的表单组件,但是在实际开发中,我们可能需要对表单进行封装,以便于复用和统一管理。以下是一些封装表单的思路: 1. 将表单组件封装成一个单独的组件,包括表单项、校验规则、提交事件等。这样可以将表单的逻辑和UI分离,方便维护和修改。 2. 使用插槽(slot)来动态渲染表单项,可以根据需要添加、删除、修改表单项,提高表单的灵活性。 3. 将表单项的校验规则封装成一个单独的对象,可以在多个表单中复用,减少代码冗余。 4. 使用v-model来双向绑定表单数据,方便获取和提交表单数据。 5. 使用ElementUI提供的表单验证规则,可以快速实现表单的校验功能,减少开发时间和代码量。 总之,封装表单可以提高代码的复用性和可维护性,同时也可以提高开发效率和代码质量。 ### 回答2: Vue是一个流行的前端框架,Element UI则是一个基于Vue框架的UI库。在Vue应用程序中使用Element UI封装form表单,可以简化表单的开发流程,并且可以提供一致性的UI风格。 Element UI提供了大量的表单组件,如输入框、下拉框、日期选择等。在Vue中使用Element UI表单组件,需要对其进行封装,以便可以更方便地使用。 首先,在Vue组件中引入ElementUI库,可以通过install方法进行注册。在组件中注册可以方便使用,同时也可以控制内部封装实现,让表单组件更加灵活地适应业务场景。 其次,需要定义表单数据模型,可以使用组件中的data对象来定义,每个数据字段对应一个表单输入框。将表单数据模型和Element UI组件双向绑定,可以实现对表单数据的自动更新。 然后,定义表单校验规则,可以使用Element UI提供的Validator组件,同时也可以自定义校验规则。在提交表单前进行表单校验,可以避免用户输入不合法数据造成数据异常。 最后,封装表单提交方法,可以使用Vue的methods方法进行实现。在提交表单时,需要将表单数据转换为JSON格式,以便可以进行后续处理。 综上所述,通过对Element UI表单组件进行封装,可以实现更加便捷、高效、可维护的表单开发。同时,也可以提高用户体验,降低用户输入错误的概率,提高数据的准确性和可靠性。 ### 回答3: Vue ElementUI是一套基于Vue.js的UI组件库,它的封装了丰富的组件和样式,使得我们在编写前端页面时可以快速搭建页面、提高开发效率。其中Form表单组件是最常用的之一。 在Vue Element UI中使用Form表单组件时,我们往往会发现它所提供的属性和方法已经足够满足我们大部分的需求。但是,在实际开发中,我们可能会遇到一些特殊的需求,需要封装一些自定义的逻辑和验证规则,比如异步校验、业务逻辑校验。这时候,我们就需要对Vue ELementUI的Form表单组件进行封装封装Form表单组件的目的就是为了封装我们常用的数据校验、提交等逻辑,提高代码的重用性和可维护性。在封装时,我们需要考虑以下几个方面: 1.表单数据的绑定: 在封装时,我们需要考虑表单数据的双向绑定,通常我们会将表单数据绑定在组件的数据对象中,并且在数据对象中提供一个reset方法,用于重置表单数据。 2.验证规则的扩展: 在Vue Element UI中,每个表单控件都可以设置相应的验证规则,比如必填、邮箱、手机号等等,但是有时候我们会遇到一些特殊的需求,比如异步校验、业务逻辑校验等,我们需要对这些验证进行特殊处理,可以通过自定义的验证方法来实现。 3.表单提交: 封装表单的最终目的就是为了实现表单的提交,并处理提交的结果。我们可以将表单的提交和结果处理封装成方法,并以事件的形式发布出去,供父组件调用。 综上所述,封装Vue ElementUI的Form表单组件可以帮助我们提高代码的重用性和可维护性,减少代码的重复编写。同时,也可以使得我们的前端页面开发更加高效,更好地实现页面交互效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值