Appearance
表格
我们封装了 Table
组件、baTable
类、baTableApi
类、表格顶部菜单
组件等,以方便快速生成和制作表格。
TIP
我们提供了一个 表格示例模块,内含大量表格使用、编程式操作的实际示例,欢迎下载体验。
Table 组件
Table
组件位于 \src\components\table
,我们基于 el-table
封装了该组件,所以 el-table 的所有事件属性都是可以直接在 Table
组件上使用的,部分属性可能失效,比如 el-table
的 size
,这是因为 Table
组件拥有一些默认的 css
样式。
组件属性
属性名 | 注释 | 值 |
---|---|---|
pagination | 是否显示底部分页组件 | boolean |
... | 其他 el-table 的属性可以直接使用 | - |
组件方法
方法名 | 注释 | 参数 |
---|---|---|
getRef | 获取内部 el-table 的 ref ,然后就可以使用 el-table 的所有方法 | - |
组件插槽
插槽名 | 注释 | 子标签 |
---|---|---|
neck | 表格头与表格主体中间区域 | 任意 |
columnPrepend | 通过此插槽在 baTable 类中定义的列之前插入列 | el-table-column |
columnAppend | 通过此插槽在 baTable 类中定义的列之后插入列 | el-table-column |
footer | 表格底部区域 | 任意 |
任意 | 列使用 render:slot, slotName:插槽名称 来使用 slot 渲染 | 任意 |
TIP
Table
组件和下方的 baTable
类是搭配使用的,baTable
类为表格提供数据,并可以响应表格组件的各种事件,组件的使用示例,也请参考下方 baTable
类的示例。
baTable 类
- 此类代码位于:
\src\utils\baTable.ts
- 我们在类里面封装好了一个表格应有的
属性
和大量方法
,预设了查看前、查看后、编辑前
等大量钩子 - 在组件上下文中,可以随时重写它的方法和修改属性值(理解这点非常重要):
- 比如重写鉴权:
baTable.auth = (node: string) => {....}
- 比如展开公共搜索组件:
baTable.table.showComSearch = true
- 比如重写鉴权:
- 可以建立新类继承
baTable
重写之后再使用(可高度自定义,重写示例:src\views\backend\security\sensitiveData\index.ts
)。
TIP
在 index.vue
文件 new baTable()
,并将实例 provide
给上下文,然后,利用它,你就可以在上下文任何组件,任何时候改变表格所有属性数据(该实例的所有属性均具备响应性),或执行任何方法,只要你代码的逻辑能实现你的需求。
使用示例
以下为使用示例,实际使用表格非常灵活,请发挥您的想象力;baTable
类支持的属性和方法,在 表格所有可用属性 有介绍,但我们更推荐您直接查阅 src\utils\baTable.ts
文件代码(有注释,不知道有哪些属性可用时,可直接查看 ts
的类型定义)
ts
<script setup lang="ts">
import Table from '/@/components/table/index.vue' // 导入 Table 组件
import baTableClass from '/@/utils/baTable' // 导入 baTable 类
import { baTableApi } from '/@/api/common' // 导入表格api方法生成器
import { defaultOptButtons } from '/@/components/table' // 导入默认表格操作按钮数据:拖拽排序、编辑、删除按钮
const tableRef = ref()
// 直接实例化 baTableClass 并传递各种参数
const baTable = new baTableClass(
new baTableApi('/admin/user.user/'), // 一个api类的实例,自动生成 index、edit、del、等url和请求方法,提供控制器url即可
{
// 表格列定义
column: [
{ type: 'selection', align: 'center', operator: false },
{ label: 'ID', prop: 'id', align: 'center', operator: 'LIKE', operatorPlaceholder: '模糊查询', width: 70 },
{ label: '用户名', prop: 'username', align: 'center', operator: 'LIKE', operatorPlaceholder: '模糊查询' },
// ...
{
label: '操作',
align: 'center',
width: '100',
render: 'buttons',
// 操作按钮传递的只是一个按钮配置数组,你也可以在渲染前对数组配置进行修改
buttons: defaultOptButtons(['edit', 'delete']),
operator: false,
},
],
// 不允许双击编辑的列的 prop
dblClickNotEditColumn: [undefined],
// ...属性很多,请参考本文下方的表格全部可用属性,或翻阅源代码(有注释)
},
)
// 实例化表格后,将 baTable 的实例提供给上下文
provide('baTable', baTable)
// 相当于表格的onMounted,也可以在页面的onMounted时执行
baTable.mount()
// 获取数据,可以在页面的onMounted时执行,也可以比如先请求一个API,再执行获取数据
baTable.getIndex()!.then(() => {
// 查看请求完毕(已获取到表格数据)
baTable.initSort() // 初始化默认排序(如果需要)
baTable.dragSort() // 初始化拖拽排序(如果需要)
})
</script>
vue
<template>
<!-- 可以直接在标签上使用 el-table 的属性和事件 -->
<Table ref="tableRef">
<template #columnPrepend>
<el-table-column prop="prepend" label="第一个列" width="180" />
</template>
<!-- baTableClass 实例中编程式定义的表格列会渲染在此处 -->
</Table>
<!-- 表格表单组件,关于它详见:https://doc.buildadmin.com/senior/web/formItem.html -->
<PopupForm />
</template>
vue
<template>
<!-- 对话框表单 -->
<!-- 建议使用 Prettier 格式化代码 -->
<!-- el-form 内可以混用 el-form-item、FormItem、ba-input 等输入组件 -->
<el-dialog
class="ba-operate-dialog"
:close-on-click-modal="false"
:model-value="['Add', 'Edit'].includes(baTable.form.operate!)"
@close="baTable.toggleForm"
width="50%"
>
<template #header>
<div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">
{{ baTable.form.operate ? t(baTable.form.operate) : '' }}
</div>
</template>
<el-scrollbar v-loading="baTable.form.loading" class="ba-table-form-scrollbar">
<div
class="ba-operate-form"
:class="'ba-' + baTable.form.operate + '-form'"
:style="config.layout.shrink ? '' : 'width: calc(100% - ' + baTable.form.labelWidth! / 2 + 'px)'"
>
<el-form
v-if="!baTable.form.loading"
ref="formRef"
@submit.prevent=""
@keyup.enter="baTable.onSubmit(formRef)"
:model="baTable.form.items"
:label-position="config.layout.shrink ? 'top' : 'right'"
:label-width="baTable.form.labelWidth + 'px'"
:rules="rules"
>
<FormItem
:label="t('test.string')"
type="string"
v-model="baTable.form.items!.string"
prop="string"
:placeholder="t('Please input field', { field: t('test.string') })"
/>
</el-form>
</div>
</el-scrollbar>
<template #footer>
<div :style="'width: calc(100% - ' + baTable.form.labelWidth! / 1.8 + 'px)'">
<el-button @click="baTable.toggleForm()">{{ t('Cancel') }}</el-button>
<el-button v-blur :loading="baTable.form.submitLoading" @click="baTable.onSubmit(formRef)" type="primary">
{{ baTable.form.operateIds && baTable.form.operateIds.length > 1 ? t('Save and edit next item') : t('Save') }}
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormInstance, FormItemRule } from 'element-plus'
import { inject, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import FormItem from '/@/components/formItem/index.vue'
import { useConfig } from '/@/stores/config'
import type baTableClass from '/@/utils/baTable'
import { buildValidatorData } from '/@/utils/validate'
const config = useConfig()
const formRef = ref<FormInstance>()
const baTable = inject('baTable') as baTableClass
const { t } = useI18n()
const rules: Partial<Record<string, FormItemRule[]>> = reactive({})
</script>
<style scoped lang="scss"></style>
表格列
表格列数据是在实例化 baTable
时定义的,此处对列数据进行了详细介绍,但表格可用属性非常多,我们更推荐您直接查阅 src\utils\baTable.ts
文件代码(有注释,不知道有哪些属性可用时,可直接查看 ts
的类型定义)
TIP
当编程式定义表格列无法满足您的需求时,请使用表格插槽或自定义单元格渲染。
ts
import baTableClass from '/@/utils/baTable'
import { baTableApi } from '/@/api/common'
const baTable = new baTableClass(new baTableApi('table controller url'), {
// 表格列数据,其中 type、align、operator 本称为列属性,所有可用属性可在下方查阅
column: [
{ type: 'selection', align: 'center', operator: false },
]
})
表格列的可用属性
ts
interface TableColumn extends Partial<TableColumnCtx<TableRow>> {
// 是否显示
show?: boolean
// 是否在下拉菜单的复选框显示 默认为 true
enableColumnDisplayControl?: boolean
// 渲染为
render?: icon|switch|image|images|tag|url|datetime|buttons|customTemplate|customRender|slot
// 操作按钮组
buttons?: OptButton[]
// 渲染为Tag时:el-tag 组件的主题
effect?: TagProps['effect']
// 渲染为Tag时:el-tag 组件的 size
size?: TagProps['size']
// 自定义数据:渲染为 Tag 时,可以指定不同值时的 Tag 的 Type 属性,示例:{ open: 'success', close: 'info' }
custom?: any
// 自定义渲染为 slot 时,slot 的名称(推荐自定义渲染方案)
slotName?: string
// 谨慎使用:自定义渲染模板,方法可返回 html 内容,请确保返回内容是 xss 安全的
customTemplate?: (row: TableRow, field: TableColumn, value: any, column: TableColumnCtx<TableRow>, index: number) => string
// 自定义组件/函数渲染
customRender?: string | Component
// 渲染为链接时,链接的打开方式
target?: aTarget
// 渲染为:url 时的点击事件,渲染为其他类型需要点击事件,直接使用 slot 自定义渲染
click?: (row: TableRow, field: TableColumn, value: any, column: TableColumnCtx<TableRow>, index: number) => any
// 渲染为 datetime 时的格式化方式,字母可以自由组合:y=年,m=月,d=日,h=时,M=分,s=秒,默认:yyyy-mm-dd hh:MM:ss
timeFormat?: string
// 默认值
default?: any
// 值替换数据,如:{open: '开'}
replaceValue?: any
// 使用了 render 属性时,渲染前对字段值的预处理方法,请返回新值
renderFormatter?: (row: TableRow, field: TableColumn, value: any, column: TableColumnCtx<TableRow>, index: number) => any
// 通用搜索操作符,默认值为=,值为 false 禁用此字段通用搜索,支持的操作符见右侧选项卡定义
operator?: boolean | OperatorStr
// 通用搜索框的placeholder
operatorPlaceholder?: string
// 公共搜索渲染方式:上方的 render=tag|switch 时公共搜索也会渲染为下拉,数字会渲染为范围筛选,时间渲染为时间选择器等
comSearchRender?: 'remoteSelect' | 'select' | 'date' | 'customRender' | 'slot'
// 公共搜索自定义组件/函数渲染
comSearchCustomRender?: string | Component
// 公共搜索自定义渲染为 slot 时,slot 的名称
comSearchSlotName?: string
// 公共搜索自定义渲染时,外层 el-col 的属性(仅 customRender、slot 支持)
comSearchColAttr?: Partial<ColProps>
// 公共搜索,是否显示字段的 label
comSearchShowLabel?: boolean
// 远程属性,目前只用于 `comSearchRender=remoteSelect`
remote?: {
pk?: string
field?: string
params?: anyObj
multiple?: boolean
remoteUrl: string
}
}
ts
type OperatorStr =
| 'eq' // 等于,默认值
| 'ne' // 不等于
| 'gt' // 大于
| 'egt' // 大于等于
| 'lt' // 小于
| 'elt' // 小于等于
| 'LIKE'
| 'NOT LIKE'
| 'IN'
| 'NOT IN'
| 'RANGE' // 范围,将生成两个输入框 以输入最小值和最大值
| 'NOT RANGE'
| 'NULL' // 是否为NULL,将生成单个复选框
| 'NOT NULL'
| 'FIND_IN_SET'
// 不推荐使用的,因为部分符号不利于网络传输
| '='
| '<>'
| '>'
| '>='
| '<'
| '<='
自定义单元格渲染
我们预设了一系列的单元格渲染方式 image、switch、tag...
,若它们不能满足您的需求,我们提供了另外三种方案,最终方案实现了完全的自定义渲染能力。
ts
import { TableColumnCtx } from 'element-plus'
// 在您使用预设的单元格渲染方案时 `icon|switch|image|tag...`
// 可以在渲染前,通过函数对单元格值进行一次处理:
const baTable = new baTableClass(
new baTableApi('admin/auth.Admin/'),
{
column: [
{
label: 'id',
prop: 'id',
render: 'tags',
// >= v2.1.2 推荐直接使用 formatter,它是由 el-table-column 自带的,新版系统自定义的单元格渲染器也使用了它格式化
formatter(row, column, cellValue, index) {
return cellValue + ' - 为该列所有值,加了个后缀'
},
// < v2.1.2 使用 renderFormatter
renderFormatter: (row: TableRow, field: TableColumn, value: any, column: TableColumnCtx<TableRow>, index: number) => {
return value + ' - 为该列所有值,加了个后缀';
}
},
]
}
)
vue
<!-- 此方案在 `BuildAdmin >= v2.0.0` 添加,实现了开发者最舒适的模式 -->
<template>
<div class="default-main">
<Table>
<!-- 请注意 #test 它是自定义的插槽名称 -->
<template #test>
<!-- 在插槽内,您可以随意发挥,通常使用 el-table-column 组件 -->
<el-table-column prop="username" label="用户名" width="180" />
<!-- 还可以继续使用 el-table-column 组件本身的插槽 -->
<el-table-column prop="id" label="ID" width="180">
<template #default="scope">
<b>{{ scope.row['id'] }}</b>
列宽度是:{{ scope.column.width }}
</template>
</el-table-column>
</template>
</Table>
</div>
</template>
<script setup lang="ts">
import baTableClass from '/@/utils/baTable'
const baTable = new baTableClass(
new baTableApi('/admin/auth.Admin/'),
{
column: [
// render: 'slot' 表示本列将使用 slot渲染
// slotName: 'test' slot的名称
{ label: '管理员', render: 'slot', slotName: 'test', operator: 'LIKE' },
]
}
)
// ...
</script>
ts
import { h, resolveComponent } from 'vue'
// renderId 即自定义的组件,你也可以直接单独建立一个 vue 文件导入使用
// 自定义组件可以接受五个 props,分别是:renderValue=单元格值,renderRow=当前行数据,renderField=当前列数据,renderColumn=当前列上下文数据,renderIndex=当前行号
const renderId = {
render(context: TableRenderPublicInstance) {
console.log(context.$attrs.renderRow, context.$attrs.renderField, context.$attrs.renderValue, context.$attrs.renderColumn, context.$attrs.renderIndex)
// 使用原生元素渲染,如`div、h1、a`等,以下演示了将 单元格值 直接通过h1标签进行渲染
return h('h1', { class: 'id-h1' }, context.$attrs.renderValue)
// 使用vue组件定义进行渲染(导入的组件)
return h(Foo, {onClick: () => {}}, context.$attrs.renderValue)
// 使用vue组件定义进行渲染(全局注册的组件)
return h(resolveComponent('el-xxx'), context.$attrs.renderValue)
},
}
const baTable = new baTableClass(
new baTableApi('/admin/auth.admin/'),
{
// id 字段将使用渲染函数进行渲染
column: [
{ label: 'id', prop: 'id', render: 'customRender', customRender: h(renderId) },
]
}
)
ts
// 自 v2.1.2 起,您可以直接建立 image、switch 等系统同级的单元格渲染器,全局使用
// 请查阅 /components/table/fieldRender/ 文件夹,其中的每个组件为一种单元格渲染器
// 组件名称即为渲染器名称,可直接将组件名于 baTable.column.render 配置使用
// 假设您参考已有渲染器建立了 /components/table/fieldRender/customRenderId.vue 组件,可如下,直接于 baTable.column 配置使用
// 建立了新的单元格渲染器后,重新执行 pnpm dev,系统还会自动更新可用渲染器的类型定义,以获得语法提示支持
// 此处不再提供渲染器内部的代码示例,因为系统已经自带了很多个定义好的,请直接复制文件->改名->修改->使用
const baTable = new baTableClass(
new baTableApi('/admin/auth.admin/'),
{
column: [
{ label: 'id', prop: 'id', render: 'customRenderId' },
]
}
)
自定义表格顶部按钮
有时您需要自定义表格顶部的按钮,请直接 点击此处查看示例代码,或者您可以参考 表格示例模块 或 数据安全管理->数据回收站
,我们在该管理功能内,通过插槽自定义了一个表格顶部的 还原
按钮(代码示例更完整)。
自定义表格行侧边按钮
有时您需要自定义表格行侧边的按钮,请参考下方示例,您也可以参考 表格示例模块 或 数据安全管理->数据回收站
,我们在该管理功能内,实例化 baTable
时定义了一个额外的表格侧边确认还原按钮。
ts
import baTableClass from '/@/utils/baTable'
import { defaultOptButtons } from '/@/components/table'
// defaultOptButtons 函数返回公共按钮数据(OptButton[])
let optBtn = defaultOptButtons(['edit', 'delete'])
// 给第一个按钮加上点击事件
optBtn[0].click = (row: TableRow, field: TableColumn) => {
console.log('点击了按钮')
}
// 自定义一个新的按钮
let newButton: OptButton[] = [
{
// 渲染方式:tipButton=带tip的按钮,confirmButton=带确认框的按钮,moveButton=移动按钮
render: 'tipButton',
// 按钮名称
name: 'info',
// 鼠标放置时的 title 提示
title: '详情',
// 直接在按钮内显示的文字,title 有值时可为空
text: '详情',
// 按钮类型,请参考 element plus 的按钮类型
type: 'primary',
// 按钮 icon
icon: 'fa fa-search-plus',
class: 'table-row-info',
// tipButton 禁用 tip
disabledTip: false,
// 自定义点击事件
click: (row: TableRow, field: TableColumn) => {},
// 按钮是否显示,请返回布尔值
display: (row: TableRow, field: TableColumn) => {
return true
},
// 按钮是否禁用,请返回布尔值
disabled: (row: TableRow, field: TableColumn) => {
return false
},
// 自定义el-button属性
attr: {}
},
]
// 新按钮合入到默认的按钮数组
optBtn = newButton.concat(optBtn)
// 实例化 baTable
const baTable = new baTableClass(new baTableApi('table controller url'), {
// 表格列数据
column: [
{ type: 'selection', align: 'center', operator: false },
{
label: '操作',
align: 'center',
width: 120,
render: 'buttons',
// 表格列,渲染为 buttons,按钮数据为上面组装好的 optBtn
buttons: optBtn,
operator: false,
},
],
})
provide('baTable', baTable)
深度使用表格(重要)
随意设置表格属性参数
表格的参数属性,在代码任何地方,都可以进行更改,比如:
ts
// 您可以先设置好一些表格属性,再执行“查看”请求
// 表格的所有可用属性,在本文下方可以寻找到,您也可以直接阅读源代码
const example1 = () => {
baTable.table.filter.limit = 20
baTable.table.filter.page = 2
baTable.table.filter!.search = [{field:'status',val:'1',operator:'=',render:'tags'}]
baTable.getIndex()
}
ts
// 数据加载完成后打开公共搜索
baTable.getIndex()?.then(() => {
baTable.table.showComSearch = true
})
自动获取表格筛选条件
有时您需要带着一些筛选条件跳转到表格,并获取筛选后的数据,您可以直接参考会员管理->编辑会员资料->调整余额;我们在跳转到余额日志管理时,携带了 user_id
参数,该参数由于和表格字段对应,所以会自动获取到并作为公共搜索的筛选条件。
ts
import router from '/@/router/index'
// 跳转到 user/moneyLog 页面,并携带 user_id 参数
router.push({
name: 'user/moneyLog',
query: {
// user_id 字段存在于 user/moneyLog 页面表格的公共搜索中
// user/moneyLog 页面内的表格公共搜索,会自动获取下列参数,如果存在,则自动填充并搜索
user_id: baTable.form.items!.id,
},
})
表格所有可用属性
ts
const baTable = new baTableClass(api,
// 表格参数
{
// 表格的ref
ref: undefined,
// 数据表主键字段
pk: 'id',
// 数据源,通过api自动加载
data: [],
// 路由remark(显示到表格顶部的文案)
remark: null,
// 表格加载状态
loading: false,
// 是否展开所有子项
expandAll: false,
// 选中项
selection: [],
// 不需要'双击编辑'的字段
dblClickNotEditColumn: [undefined],
// 列数据
column: [],
// 数据总量
total: 0,
// 字段搜索,快速搜索,分页等数据
filter: {
limit: 10,
page: 1,
order: 'createtime',
// 快速搜索,指定字段请在对应后端控制器内定义,默认为id
quick_search: '快速搜索关键词',
// 公共搜索
search: [
{
'field': 'title',
'val': '搜索标题字段',
'operator': 'LIKE',
'render': 'tags',
}
]
},
// 拖动排序限位字段:例如拖动行pid=1,那么拖动目的行pid也需要为1
dragSortLimitField: 'pid',
// 接受url的query参数并自动触发通用搜索
acceptQuery: true,
// 显示公共搜索
showComSearch: false,
// 扩展数据,预设的随意定义字段,整个baTable通常会暴露到上下文,定义后可在上下文中使用此属性
extend: {},
},
// 表单参数
{
// 表单ref,new时无需传递
ref: undefined,
// 表单label宽度
labelWidth: 160,
// 当前操作:add=添加,edit=编辑
operate: '',
// 被操作数据ID,支持批量编辑:add=[0],edit=[1,2,n]
operateIds: [],
// 表单数据,编辑/添加时的表单字段当前输入和预加载的数据
items: {},
// 提交按钮状态
submitLoading: false,
// 默认表单数据(添加)
defaultItems: {
username: '默认用户名',
nickname: '默认昵称',
},
// 表单字段加载状态
loading: false,
// 扩展数据,预设的随意定义字段,整个baTable通常会暴露到上下文,定义后可在上下文中使用此属性
extend: {},
},
// 操作前置方法列表,返回false则取消原操作
{
getIndex: () => boolean,// 查看前
postDel: ({ids}: {ids: string[]}) => boolean,// 删除前
requestEdit: ({ id }: { id: string }) => boolean,// 编辑请求前
onTableDblclick: ({ row, column }: { row: TableRow; column: TableColumn }) => boolean,// 双击表格具体操作执行前
toggleForm:({ operate, operateIds }: { operate: string; operateIds: string[] }) => boolean,// 表单切换前
onSubmit:({ formEl, operate, items }: { formEl: FormInstance | undefined; operate: string; items: anyObj }) => boolean,// 表单提交前
onTableAction: ({ event, data }: { event: string, data: anyObj }) => boolean,// 表格内事件响应前
onTableHeaderAction: ({ event, data }: { event: string, data: anyObj }) => boolean,// 表格顶部菜单响应前
mount: () => boolean,// 初始化前
},
// 操作后置方法列表,先执行表格本身的查看、删除、编辑、双击、等,再执行本处添加的后置操作
{
getIndex: ({ res }: { res: ApiResponse }) => void,// 查看后
postDel: ({ res }:{ res: ApiResponse }) => void,// 删除后
requestEdit: ({ res }: {res: ApiResponse}) => void,// 编辑请求后
onTableDblclick: ({ row, column }: {row: TableRow, column: TableColumn}) => void,// 双击表格具体操作执行后
toggleForm:({ operate, operateIds }: {operate: string, operateIds: string[]}) => void,// 表单切换后
onSubmit:({ res }: {res: ApiResponse}) => void,// 表单提交后
onTableAction: ({ event, data }: { event: string, data: anyObj }) => void,// 表格内事件响应后
onTableHeaderAction: ({ event, data }: {event: string, data: anyObj}) => void,// 表格顶部菜单响应后
}
)
重写 baTable 类方法
baTable
在双击单元格、刷新、提交等操作前,均提供了钩子,如果这些钩子不能满足您的需求,您还可以重写 baTable
类方法的实现:
ts
const baTable = new baTableClass(...)
// 重写表格内部的鉴权方法
baTable.auth = (node: string) => {
return true
// return auth({ name: '/admin/user/user', subNodeName: '/admin/user/user/' + node })
}
表格公共搜索
表格公共/通用搜索是在实例化 baTable
时定义的,表格列的 render、operator、comSearchRender
属性共同参与公共搜索框的渲染。comSearchRender
支持 remoteSelect、select、date、customRender、slot
,详细使用方法请直接查看下方示例代码。
render | operator | comSearchRender | 公共搜索渲染 |
---|---|---|---|
任意 | false | 不渲染 | |
任意 | RANGE、NOT RANGE | 生成两个输入框(A和B),可输入从A到B 的范围值 | |
任意 | NULL、NOT NULL | 生成一个复选框,勾选则搜索值为NULL、NOT NULL 的情况 | |
datetime | RANGE、NOT RANGE | 时间范围选择器 | |
datetime | =、>、< 等比较符号,请参考 表格列 的 operator 属性 | 时间选择器 | |
tag | =、>、< 等比较符号 | 生成下拉框,下拉列表定义请参考 表格列 的 replaceValue | |
switch | 无需设定 | 生成下拉框: 1=开,0=关 ,也可以通过设置 表格列 的 replaceValue 自定义值 | |
任意 | 表格列 的其他 operator 属性 | 生成普通字符串输入框 | |
任意 | =、>、< 等比较符号 | remoteSelect | 远程下拉 |
任意 | =、>、< 等比较符号 | select | 下拉框 |
任意 | 无需设定 | date | 日期选择器(纯日期无时间) |
datetime | RANGE、NOT RANGE | date | 日期范围选择器(纯日期无时间) |
任意 | 任意 | customRender | 自定义渲染组件,请参考下方示例 |
公共搜索示例代码
ts
import baTableClass from '/@/utils/baTable'
import { baTableApi } from '/@/api/common'
import { userUser } from '/@/api/controllerUrls'
const baTable = new baTableClass(new baTableApi('table controller url'), {
// 定义表格列数据、同时定义公共/通用搜索数据
column: [
// 关闭这个字段的公共搜索
{ type: 'selection', align: 'center', operator: false },
// 此字段是模糊查找,并为公共搜索输入框设置了 placeholder
{ label: 'ID', prop: 'id', align: 'center', operator: 'LIKE', operatorPlaceholder: t('Fuzzy query'), width: 70 },
// 此字段是图片,建议关闭公共搜索
{ label: '头像', prop: 'avatar', align: 'center', render: 'image', operator: false },
// 此字段将生成一个下拉框选择进行搜索,拥有三个值
{
label: t('user.user.Gender'),
prop: 'gender',
align: 'center',
render: 'tag',
replaceValue: { '0': t('unknown'), '1': t('user.user.male'), '2': t('user.user.female') },
},
// 此字段将生成一个时间范围选择框,选择时间日期进行搜索
{ label: t('createtime'), prop: 'createtime', align: 'center', render: 'datetime', sortable: 'custom', operator: 'RANGE', width: 160 },
// 此字段将生成一个日期范围选择框,选择日期进行搜索(请注意渲染还是 datetime 若需自定义单元格渲染请参考`表格列`一节)
{ label: t('updatetime'), prop: 'updatetime', align: 'center', render: 'datetime', sortable: 'custom', operator: 'RANGE', width: 160, comSearchRender: 'date' },
// 另外一种在公共搜索渲染下拉框的办法
{
label: t('user.user.Gender'),
prop: 'gender',
align: 'center',
comSearchRender: 'select',
replaceValue: { '0': t('unknown'), '1': t('user.user.male'), '2': t('user.user.female') },
},
// 远程下拉选择框
{ label: '会员', prop: 'user_id', comSearchRender: 'remoteSelect', remote: {
// 主键,下拉 value
pk: 'id',
// 字段,下拉 label
field: 'username',
// 远程接口URL
// 比如想要获取 user(会员) 表的数据,后台`会员管理`控制器URL为`/index.php/admin/user.user/index`
// 因为已经通过 CRUD 生成过`会员管理`功能,所以该URL地址可以从`/@/api/controllerUrls`导入使用,如下面的 userUser
// 该URL地址通常等于对应后台管理功能的`查看`操作请求的URL
remoteUrl: userUser + 'index',
// 额外的请求参数
params: {},
}},
]
})
完全自定义公共搜索的渲染
vue
// 此方案在 `BuildAdmin >= v2.0.0` 添加,实现了开发者最舒适的模式
<template>
<div class="default-main">
<TableHeader
:buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay']"
:quick-search-placeholder="t('Quick search placeholder', { fields: t('auth.admin.username') + '/' + t('auth.admin.nickname') })"
>
<!-- 请注意 #test 它是自定义的插槽名称 -->
<template #test>
<!-- 在插槽内,您可以随意发挥,通常渲染一个输入框供用户输入内容 -->
<!-- 输入组件的 v-model="baTable.comSearch.form[item.prop!]" 即可在baTable上下文获取用户输入的关键词 -->
我是公共搜索的slot渲染内容
</template>
</TableHeader>
<Table />
</div>
</template>
<script setup lang="ts">
import baTableClass from '/@/utils/baTable'
const baTable = new baTableClass(
new baTableApi('/admin/auth.Admin/'),
{
column: [
// comSearchRender: 'slot' 表示本字段的公共搜索将使用 slot渲染
// comSearchSlotName: 'test' slot的名称
{ label: '管理员', prop: 'username', operator: 'LIKE', comSearchRender:'slot', comSearchSlotName: 'test' },
]
}
)
// ...
</script>
ts
import { h, resolveComponent } from 'vue'
// searchId 即自定义的组件,你也可以直接单独建立一个 vue 文件导入使用
// 自定义组件可以接受三个 props,分别是:renderRow=当前行数据,renderField=当前列数据,renderValue=搜索框绑定值
const searchId = {
render(context: TableRenderPublicInstance) {
console.log(context.$attrs.renderRow, context.$attrs.renderField, context.$attrs.renderValue)
// 使用原生元素渲染
return h('input', { class: 'id-h1' }, context.$attrs.renderValue)
// 使用vue组件定义进行渲染(全局注册的组件)
return h(resolveComponent('el-input'), context.$attrs.renderValue)
},
}
const baTable = new baTableClass(
new baTableApi('/admin/auth.admin/'),
{
// id 字段的公共搜索将使用 searchId 组件进行渲染
// 与单元格的完全自定义渲染只是属性名不同
column: [
{ label: 'id', prop: 'id', comSearchRender: 'customRender', comSearchCustomRender: h(searchId) },
]
}
)
方案三:弃用表格自带的公共搜索
- 请参考表格顶部组件,禁用掉公共搜索
- 完整实现一个自定义的公共搜索组件
- 然后你可以通过
baTable.table.showComSearch
来判断您自定义公共搜索组件的显示隐藏状态
baTableApi 类
此类代码位于:\src\api\common.ts
,它实现快速生成一个控制器的:增、删、改、查、排序
的操作 url
和请求方法,提供控制器的 url
即可。此类通常与 baTable
类搭配使用,若需单独定义 api
请求函数,可以直接在 \src\api
目录下定义,无需经过 baTableApi
。
使用示例
vue
<script>
import { baTableApi } from '/@/api/common' // 导入表格api方法生成器
// 请注意,baTableApi类的方法通常都是由baTable类来使用的,并不是在外部示例化一个 baTableApi 类使用,以下仅为方便读者理解它是什么
let baApi = new baTableApi('/admin/user.user/')
baApi.index({}) // 请求查看,参数为筛选条件,具体使用请参考baTable类
baApi.edit({}) // 请求编辑数据,参数为被编辑项id等
baApi.del({}) // 请求删除,参数为被删除数据的ids
// ...
</script>
表格顶部组件
TableHeader
组件内含有公共搜索和表头操作按钮,菜单按钮可以自动根据当前路由进行 鉴权
,当前管理员无权限的按钮,则不会显示。
属性列表
属性名 | 注释 |
---|---|
buttons | 要显示的按钮数组,比如 ['refresh', 'add', 'comSearch'] ,即表示于表格顶部显示 刷新、添加、公共搜索 按钮 |
quick-search-placeholder | 快速搜索输入框的 placeholder |
插槽列表
插槽名 | 注释 |
---|---|
refreshPrepend | 刷新按钮前插槽 |
refreshAppend | 刷新按钮后插槽 |
— | 此插槽内容将放置在组件内置的菜单按钮之后,可自定义表格顶部按钮等 |
quickSearchPrepend | 快速搜索前插槽 |
任意 | 列配置中使用 comSearchRender:'slot', comSearchSlotName: 插槽名称 来通过slot 渲染公共搜索 |
支持的菜单按钮
菜单按钮 | 注释 |
---|---|
refresh | 刷新按钮 |
add | 添加 |
edit | 编辑 |
delete | 删除 |
comSearch | 公共搜索 |
quickSearch | 快速搜索 |
columnDisplay | 字段显示状态 |
unfold | 展开/折叠,与 baTable.table.expandAll 属性关联 |
表格顶部菜单示例代码
src/views/backend/security/dataRecycleLog/index.vue
文件
vue
<template>
<!-- buttons 属性定义了 TableHeader 本身支持的顶部按钮,仅需传递按钮名即可 -->
<TableHeader
:buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay', 'unfold']"
:quick-search-placeholder="t('Quick search placeholder', { fields: t('security.dataRecycleLog.Rule name') })"
>
<!-- 可以在此处以插槽的方式设置一些自定义按钮 -->
<template #refreshPrepend>
<!-- 刷新按钮前插槽内容 -->
</template>
<!-- 默认插槽 -->
<template #default>
<el-button v-blur :disabled="baTable.table.selection!.length > 0 ? false:true" class="table-header-operate" type="success">
<Icon color="#ffffff" name="el-icon-RefreshRight" />
<span class="table-header-operate-text">还原</span>
</el-button>
</template>
</TableHeader>
</template>
<script>
import TableHeader from '/@/components/table/header/index.vue'
</script>
常见问题
如何在一个页面渲染两个表格?
由于表格数据来自 baTable
实例,并且通过 provide
、inject
将整个实例传递给组件上下文,所以,两个表格不能共处于一个 vue
文件中,您可以另外建立 vue
文件,在其中写好新的表格,然后导入使用即可。
如何禁用列的双击编辑功能?
我们可以通过添加列的 prop
到 baTable
的 dblClickNotEditColumn数组
来禁用对应列的双击编辑功能,当我们想禁用全部列的双击编辑功能时只需要定义 dblClickNotEditColumn: ['all']
即可。