configurable-component
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.2 • Public • Published

    configurable-component

    NPM Version Build Status NPM Download

    是个组件库

    基于element-ui二次封装,现阶段主要处理表单和表格,快速完成增删改查操作。

    组件文档,目前用的github page,有点慢。或者拉代码本地查看文档

    git clone https://github.com/dyw934854565/configurable-component.git
    cd configurable-component
    npm install
    npm start

    简化原理

    牺牲了一部分的可扩展性,构建更简单调用的组件。更少的使用slot,更多的通过props来完成定制化需求。

    保证单个组件纯使用props来做定制化需求,更方便的将多个不同的组件组合成新的组件,通过组件props透传来保证子组件的可定制化。这样的好处是组合组件可以处理组件间通用的逻辑,简单的来说就是高阶组件,这样不用反复去写相同的逻辑。

    相同的逻辑,比如有,分页页码变动,表格数据请求;弹窗修改数据,点保存,需要做表单数据的验证,保存按钮置灰,以防止重复请求。等等,还有更多

    保证可扩展性

    现在的大部分组件,为了可扩展性,会用slot。比如el-option,简单使用如下

    <el-option>{{item.label}}</el-option>

    其slot不仅可以放字符串,还可以放一些自定义模版。对于基础组件来说,它要满足各种奇葩的需求,保证可扩展性是很重要的一件事。

    <template>
    <el-select>
        <el-option :value="item.value" v-for="item in options">
            <span style="float: left">{{ item.label }}</span>
            <span style="float: right; color: #8492a6; font-size: 13px">{{ item.value }}</span>
        </el-option>
    </el-select>
    </template>

    这样对于自定义需求来说极为方便,但是,对于el-select来说,大部分需求,只需要简单默认模版,每次都要拿到options数组自己写一遍v-for,很浪费时间。

    如果select增加options参数,使用固定的模版,就可以不用重复写v-for了。当然,好处不止于此,如果表单项组件都可以通过参数配置,那么el-from,可以一个form数组配置表单项,各种组件可以混搭。

    这样做的问题就是一棒子打死了可扩展性,不过还是有一些补救的办法的。在固定模板中使用component,可以弥补大部分情况下的可扩展性

    大概使用如下:

    <template>
    <el-select>
        <el-option :value="item.value" v-for="item in options">
            <component
                v-if="item.component"
                :is="item.component"
                :label="item.label"
                v-bind="item.props || {}"
                v-on="item.listeners || {}"
            />
            <template v-else>
                {{item.label}}
            <template>
        </el-option>
    <el-select>
    <template>

    item.component可以是字符串(已注册组件的名字)或一个组件的选项对象(从.vue文件import/Vue.extend的返回值)。

    想扩展没那么方便了,但是带来的收益也很明显。对于一个项目来说,扩展内容一般会一致,保证用户体验一致,所以使用component也不一定不好,也可能是更方便。

    这样写,可能会多很多v-if,可能有一些性能问题,这个具体没测。未来考虑

    这样我们基于这个可以封装自己的select

    <template>
    <my-select
        :value="value"
        :options="[{value: 'value', label: 'label'}]"
    >
    <my-select>
    <template>

    当我们能解决了select这种表单项的可复用性问题

    我们可以基于此做配置项的form组件

    <template>
    <my-form
        :model.sync="model"
        :forms="[{key: 'sex', component: 'my-select', label: 'label', extra: {}, listeners: {onChange: () => {}}}]"
    >
    <my-form>
    <template>

    事件处理

    <template>
    <component
        v-if="item.component"
        :is="item.component"
        v-bind="item.props || {}"
        v-on="item.listeners || {}"
    />
    <template>
     

    转化成函数参数

    <template>
    <el-button :loading="loading"  @click="onClick">
        submit
    </el-button>
    <template>
     
    <script>
    export default {
        props: {
            onSubmit: {
                type: Function,
                required: true
            }
        },
        data() {
            return { loading: false };
        },
        methods: {
            async onClick() {
                try {
                    this.loading = true;
                    await this.onSubmit();
                } catch (e) {
                    this.$message.error(e.message)
                }
                this.loading = false;
            }
        }
    }
    </script>
    methods: {
        newOrEditItem(type = '新建', initData = {}, index) {
            this.$dataDialog(
                {
                    onValidate: this.editOrSave.bind(this),
                    forms: this.forms,
                    initData,
                    // key: 'edit', 如果想保持没保存的数据,可以设置key
                    formExtra: {
                        'label-width': '140px'
                    },
                    msgBox: {
                        title: type + this.title
                    }
                }
            )
        }
    }

    数据获取

    <template>
    <el-table :loading="loading"  @data="[]">
    </el-table>
    <template>
    <template>
    <el-table  @data="function() {return Promise<[]>}">
    </el-table>
    <template>

    测试用例

    慢慢补吧,易代码还有优化空间,还是优先优化代码

    LICENSE

    MIT License

    Install

    npm i configurable-component

    DownloadsWeekly Downloads

    13

    Version

    1.0.2

    License

    MIT

    Unpacked Size

    1.06 MB

    Total Files

    46

    Last publish

    Collaborators

    • dyw934854565