JeecgBoot 自定义组件说明文档(二)

1,495 阅读7分钟

JEditableTable 帮助文档

参数配置

参数类型必填说明
columnsarray✔️表格列的配置描述,具体项见下表
dataSourcearray✔️表格数据
loadingboolean是否正在加载,加载中不会显示任何行,默认false
actionButtonboolean是否显示操作按钮,包括"新增"、"删除",默认false
rowNumberboolean是否显示行号,默认false
rowSelectionboolean是否可选择行,默认false
dragSortboolean是否可拖动排序,默认false
dragSortKeystring拖动排序存储的Key,无需定义在columns内也能在getValues()时获取到值,默认orderNum
maxHeightnumber设定最大高度(px),默认400
disabledRowsobject设定禁用的行,被禁用的行无法被选择和编辑,配置方法可以查看示例
disabledboolean是否禁用所有行,默认false

columns 参数详解

参数类型必填说明
titlestring✔️表格列头显示的问题
keystring✔️列数据在数据项中对应的 key,必须是唯一的
typestring✔️表单的类型,可以通过JEditableTableUtil.FormTypes赋值
widthstring列的宽度,可以是百分比,也可以是px或其他单位,建议设置为百分比,且每一列的宽度加起来不应超过100%,否则可能会不能达到预期的效果。留空会自动计算百分比
placeholderstring表单预期值的提示信息,可以使用${...}变量替换文本(详见${...} 变量使用方式
defaultValuestring默认值,在新增一行时生效
validateRulesarray表单验证规则,配置方式见validateRules 配置规则
propsobject设置添加给表单元素的自定义属性,例如:props:{title: 'show title'}
disabledboolean是否禁用当前列,默认false
当 type=checkbox 时所需的参数
参数类型必填说明
defaultCheckedboolean默认值是否选中
customValuearray自定义值,checkbox需要的是boolean值,如果数据是其他值(例如'Y' or 'N')时,就会导致错误,所以提供了该属性进行转换,例:customValue: ['Y','N'],会将true转换为'Y'false转换为'N',反之亦然
当 type=select 时所需的参数
参数类型必填说明
optionsarray✔️下拉选项列表,详见下表
allowInputboolean是否允许用户输入内容,并创建新的内容
dictCodeString数据字典Code,若options也有值,则拼接在options后面

options 所需参数

参数类型必填说明
textstring✔️显示标题
valuestring✔️真实值
titlestring显示标题(已废弃,若同时填写了 title 和 text 那么优先使用 text)
当 type=upload 时所需的参数
参数类型必填说明
actionstring✔️上传文件路径
tokenboolean上传的时候是否传递token
responseNamestring✔️若要从上传成功后从response中取出返回的文件名,那么这里填后台返回的包含文件名的字段名
当 type=slot 时所需的参数
参数类型必填说明
slotNamestring✔️slot的名称

validateRules 配置规则

validateRules 需要的是一个数组,数组里每项都是一个规则,规则是object类型,规则的各个参数如下

  • required 是否必填,可选值为trueorfalse
  • pattern 正则表达式验证,只有成功匹配该正则的值才能成功通过验证
  • handler 自定义函数校验,使用方法请见示例五
  • message 当验证未通过时显示的提示文本,可以使用${...}变量替换文本(详见${...} 变量使用方式
  • 配置示例请看示例二

事件

事件名触发时机参数
added当添加行操作完成后触发
deleted当删除行操作完成后触发(批量删除操作只会触发一次)deleteIds 被逻辑删除的id
selectRowChange当行被选中或取消选中时触发selectedRowIds 被选中行的id
valueChange当数据发生改变的时候触发的事件{ type, row, column, value, target } Event对象

方法

关于方法的如何调用的问题,请在FAQ中查看方法如何调用

initialize

用于初始化表格(清空表格)

  • 参数:
  • 返回值:
resetScrollTop

重置滚动条Top位置

  • 参数:
参数名类型必填说明
topnumber新top位置,留空则滚动到上次记录的位置,用于解决切换tab选项卡时导致白屏以及自动将滚动条滚动到顶部的问题
  • 返回值:
add

主动添加行,默认情况下,当用户的滚动条已经在底部的时候,会将滚动条固定在底部,即添加后无需用户手动滚动,而会自动滚动到底部

  • 参数:
参数名类型必填说明
numnumber添加几行,默认为1
forceScrollToBottomboolean是否在添加后无论用户的滚动条在什么位置都强制滚动到底部,默认为false
  • 返回值:
removeRows

主动删除一行或多行

  • 参数:
参数名类型必填说明
idstring 或 array✔️被删除行的id。如果要删除一个,可以直接传id,如果要删除多个,需要将多个id封装成一个数组传入
  • 返回值:
removeSelectedRows

主动删除被选中的行

  • 参数:
  • 返回值:
getValues

用于获取表格里所有表单的值,可进行表单验证

  • 参数:
参数名类型必填说明
callbackfunction✔️获取值的回调方法,会传入errorvalues两个参数。error:未通过验证的数量,当等于0时代表验证通过;values:获取的值(即使未通过验证该字段也有数据)
validateboolean是否进行表单验证,默认为true,设为false则代表忽略表单验证
rowIdsarray默认返回所有行的数据,如果传入了rowIds,那么就会只返回与该rowIds相匹配的数据,如果没有匹配的数据,就会返回空数组
  • 返回值:
getValuesSync

getValues的同步版,会直接将获取到的数据返回

  • 参数:
参数名类型必填说明
optionsobject选项,详见下方所需参数
    • options 所需参数
参数名类型必填说明
validateboolean是否进行表单验证,默认为true,设为false则代表忽略表单验证
rowIdsarray默认返回所有行的数据,如果传入了rowIds,那么就会只返回与该rowIds相匹配的数据,如果没有匹配的数据,就会返回空数组
  • 返回值: object

    • error 未通过验证的数量,当等于0时代表验证通过
    • values 获取的值(即使未通过验证该字段也有数据)
  • 使用示例

let { error, values } = this.$refs.editableTable.getValuesSync({ validate: true, rowIds: ['rowId1', 'rowId2'] })
if (error === 0) {
    console.log('表单验证通过,数据:', values);
} else {
    console.log('未通过表单验证,数据:', values);
}
getValuesPromise

getValues的promise版,会在resolve中传入获取到的值,会在reject中传入失败原因,例如VALIDATE_NO_PASSED

  • 参数:
参数名类型必填说明
validatebooleangetValuesvalidate参数
rowIdsarray默认返回所有行的数据,如果传入了rowIds,那么就会只返回与该rowIds相匹配的数据,如果没有匹配的数据,就会返回空数组
  • 返回值: Promise
getDeleteIds

用于获取被逻辑删除的行的id,返回一个数组,用户可将该数组传入后台,并进行批量删除

  • 参数:
  • 返回值: array
getAll

获取所有的数据,包括values、deleteIds 会在resolve中传入获取到的值:{values, deleteIds} 会在reject中传入失败原因,例如VALIDATE_NO_PASSED

  • 参数:
参数名类型必填说明
validatebooleangetValuesvalidate参数
  • 返回值: Promise
setValues

主动设置表格中某行某列的值

  • 参数:
参数名类型必填说明
valuesarray传入一个数组,数组中的每项都是一行的新值,具体见下面的示例
  • 返回值:
  • 示例:
setValues([
    {
        rowKey: id1, // 行的id
        values: { // 在这里 values 中的 name 是你 columns 中配置的 key
            'name': 'zhangsan',
            'age': '20'
        }
    },
    {
        rowKey: id2,
        values: {
            'name': 'lisi',
            'age': '23'
        }
    }
])
clearSelection

主动清空选择的行

  • 参数:
  • 返回值:

内置插槽

插槽名说明
buttonBefore在操作按钮的前面插入插槽,不受actionButton属性的影响
buttonAfter在操作按钮的后面插入插槽,不受actionButton属性的影响

${...} 变量使用方式

placeholdermessage这两个属性中可以使用${...}变量来替换文本 在示例二中,配置了title名称的一列,而placeholder配置成了请输入${title},那么最终显示效果为请输入名称 这就是${...}变量的使用方式,在${}中可以使用的变量有titlekeydefaultValue这三个属性的值


JEditableTableUtil 使用说明

在之前配置columns时提到过JEditableTableUtil这个工具类,那么如果想要知道详细的使用说明就请看这里

export 的常量

FormTypes

这是配置columns.type时用到的常量值,其中包括

  • normal 默认,直接显示值,不渲染表单
  • input 显示输入框
  • inputNumber 显示数字输入框
  • checkbox 显示多选框
  • select 显示选择器(下拉框)
  • date 日期选择器
  • datetime 日期时间选择器
  • upload 上传组件(文件域)
  • slot 自定义插槽

VALIDATE_NO_PASSED

在判断表单验证是否通过时使用,如果 reject 的值 === VALIDATE_NO_PASSED 则代表表单验证未通过,你可以做相应的其他处理,反之则可能是发生了报错,可以使用 console.error 输出

封装的方法

validateTables

当你的页面中存在多个JEditableTable实例的时候,如果要获取每个实例的值、判断表单验证是否通过,就会让代码变得极其冗余、繁琐,于是我们就将该操作封装成了一个函数供你调用,它可以同时获取并验证多个JEditableTable实例的值,只有当所有实例的表单验证都通过后才会返回值,否则将会告诉你具体哪个实例没有通过验证。具体使用方法请看下面的示例

  • 参数:
参数名类型必填说明
casesarray传入一个数组,数组中的每项都是一个JEditableTable的实例
  • 返回值: Promise
  • 示例:
import { validateTables, VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
// 封装cases
let cases = []
cases.push(this.$refs.editableTable1)
cases.push(this.$refs.editableTable2)
cases.push(this.$refs.editableTable3)
cases.push(this.$refs.editableTable4)
cases.push(this.$refs.editableTable5)
// 同时验证并获取多个实例的值
validateTables(cases).then((all) => {
    // all 是一个数组,每项都对应传入cases的下标,包含values和deleteIds
    console.log('所有实例的值:', all)
}).catch((e = {}) => {
    // 判断表单验证是否未通过
    if (e.error === VALIDATE_NO_PASSED) {
        console.log('未通过验证的实例下标:', e.index)
    } else {
        console.error('发生异常:', e)
    }
})

FAQ

方法如何调用?

示例一中,设定了一个 ref="editableTable" 的属性,那么在vue中就可以使用this.$refs.editableTable获取到该表格的实例,并调取其中的方法。 假如我要调取initialize方法,就可以这么写:this.$refs.editableTable.initialize()

如何获取表单的值?

使用getValue方法进行获取,详见示例三

如何进行表单验证?

在获取值的时候默认会进行表单验证操作,用户在输入的时候也会对正在输入的表单进行验证,只要配置好规则就可以了

如何添加或删除一行?

该功能已封装到组件中,你只需要将 actionButton 设置为 true 即可,当然你也可以在代码中主动调用新增方法或修改,具体见上方的方法介绍。

为什么使用了ATab组件后,切换选项卡会导致白屏或滚动条位置会归零?

在ATab组件中确实会导致滚动条位置归零,且不会触发onscroll方法,所以无法动态加载行,导致白屏的问题出现。 解决方法是在ATab组件的onChange事件触发时执行实例提供的resetScrollTop()方法即可,但是需要注意的是:代码主动改变ATab的activeKey不会触发onChange事件,还需要你手动调用下。

  • 示例
<template>
    <a-tabs @change="handleChangeTab">
        <a-tab-pane tab="表格1" :forceRender="true" key="1">
            <j-editable-table
                ref="editableTable1"
                :loading="tab1.loading"
                :columns="tab1.columns"
                :dataSource="tab1.dataSource"/>
        </a-tab-pane>
        <a-tab-pane tab="表格2" :forceRender="true" key="2">
            <j-editable-table
                ref="editableTable2"
                :loading="tab2.loading"
                :columns="tab2.columns"
                :dataSource="tab2.dataSource"/>
        </a-tab-pane>
    </a-tabs>
</template>
/*--- 忽略部分代码片段 ---*/
methods: {

      /** 切换tab选项卡的时候重置editableTable的滚动条状态 */
      handleChangeTab(key) {
        this.$refs[`editableTable${key}`].resetScrollTop()
      }

}
/*--- 忽略部分代码片段 ---*/

slot(自定义插槽)如何使用?

代码示例请看:示例四(slot)


示例一

<j-editable-table
    ref="editableTable"
    :loading="loading"
    :columns="columns"
    :dataSource="dataSource"
    :rowNumber="true"
    :rowSelection="true"
    :actionButton="true"
    style="margin-top: 8px;"
    @selectRowChange="handleSelectRowChange"/>

示例二


import { FormTypes } from '@/utils/JEditableTableUtil'

/*--- 忽略部分代码片断 ---*/
columns: [
    {
        title: '名称',
        key: 'name',
        type: FormTypes.input,
        placeholder: '请输入${title}',
        defaultValue: '称名',
        // 表单验证规则
        validateRules: [
            {
                required: true, // 必填
                message: '${title}不能为空' // 提示的文本
            },
            {
                pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
                message: '${title}必须以字母开头,可包含数字、下划线、横杠'
            }
        ]
    },
    {
        title: '年龄',
        key: 'age',
        type: FormTypes.inputNumber,
        placeholder: '请输入${title}',
        defaultValue: 18,
        validateRules: [{required: true, message: '${title}不能为空'}]
    }
]
/*--- 忽略部分代码片断 ---*/

示例三

// 获取被逻辑删除的字段id
let deleteIds = this.$refs.editableTable.getDeleteIds();
// 获取所有表单的值,并进行验证
this.$refs.editableTable.getValues((error, values) => {
    // 错误数 = 0 则代表验证通过
    if (error === 0) {
        this.$message.success('验证通过')
        // 将通过后的数组提交到后台或自行进行其他处理
        console.log(deleteIds, values)
    } else {
        this.$message.error('验证未通过')
    }
})

示例四(slot)

<template>
    <j-editable-table :columns="columns" :dataSource="dataSource">
        <!-- 定义插槽 -->
        <!-- 这种定义插槽的写法是vue推荐的新版写法(https://cn.vuejs.org/v2/guide/components-slots.html#具名插槽),旧版已被废弃的写法不再支持 -->
        <!-- 若webstorm这样写报错,请看这篇文章:https://blog.csdn.net/lxq_9532/article/details/81870651 -->
        <template v-slot:action="props">
            <a @click="handleDelete(props)">删除</a>
        </template>
    </j-editable-table>
</template>
<script>
    import { FormTypes } from '@/utils/JEditableTableUtil'
    import JEditableTable from '@/components/jeecg/JEditableTable'
    export default {
        components: { JEditableTable },
        data() {
            return {
                columns: [
                    // ...
                    {
                        title: '操作',
                        key: 'action',
                        width: '8%',
                        type: FormTypes.slot, // 定义该列为 自定义插值列 
                        slotName: 'action' // slot 的名称,对应 v-slot 冒号后面和等号前面的内容
                    }
                ]
            }
        },
        methods: {
            /* a 标签的点击事件,删除当前选中的行 */
            handleDelete(props) {
                // 参数解释
                // props.index :当前行的下标
                // props.text :当前值,可能是defaultValue定义的值,也可能是从dataSource中取出的值
                // props.rowId :当前选中行的id,如果是新增行则是临时id
                // props.column :当前操作的列
                // props.getValue :这是一个function,执行后可以获取当前行的所有值(禁止在template中使用)
                //                  例:const value = props.getValue()
                // props.target :触发当前事件的实例,可直接调用该实例内的方法(禁止在template中使用)
                //                  例:target.add()

                // 使用实例:删除当前操作的行
                let { rowId, target } = props
                target.removeRows(rowId)
            }
        }
    }
</script>

示例五

// 该示例是自定义函数校验
columns: [
    {
        title: '字段名称',
        key: 'dbFieldName',
        type: FormTypes.input,
        defaultValue: '',
        validateRules: [
            {
                // 自定义函数校验 handler
                handler(type, value, row, column, callback, target) {
                    // type 触发校验的类型(input、change、blur)
                    // value 当前校验的值
                    // callback(flag, message) 方法必须执行且只能执行一次
                    //          flag = 是否通过了校验,不填写或者填写 null 代表不进行任何操作
                    //          message = 提示的类型,默认使用配置的 message
                    // target 行编辑的实例对象

                    if (type === 'blur') {

                        if (value === 'abc') {
                            callback(false, '${title}不能是abc') // false = 未通过,可以跟自定义提示
                            return
                        }

                        let { values } = target.getValuesSync({ validate: false })
                        let count = 0
                        for (let val of values) {
                            if (val['dbFieldName'] === value) {
                                if (++count >= 2) {
                                    callback(false, '${title}不能重复')
                                    return
                                }
                            }
                        }
                        callback(true) // true = 通过验证
                    } else {
                        callback() // 不填写或者填写 null 代表不进行任何操作
                    }
                },
                message: '${title}默认提示'
            }
        ]
    },
]