## 万能表格
### 核心思想:通过 JSON 配置渲染规则
### 基础用法
```html
```
```js
export default {
data() {
// 页面数据变量
return {
table1:{
// 表格数据
data:[],
// 表格字段显示规则
columns:[
{ key:"_id" , title:"用户ID" , type:"text" , width:200 },
{ key:"username" , title:"用户名" , type:"text" , width:200 },
{ key:"nickname" , title:"用户昵称" , type:"text" , width:200 },
{ key:"mobile" , title:"手机号" , type:"text" , width:200 },
{ key:"comment" , title:"备注" , type:"text" , minWidth:200 },
]
}
};
}
};
```
### 进阶用法
### 请直接看示例文件 `/pages_template/components/table/table-easy`
## API
### 属性
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|------------------|-------------------------------|---------|--------|-------|
| action | 动态模式 - vk框架下的云函数地址 | String | 无 | - |
| auto-action | 动态模式 - 是否组件加载完毕后自动运行action | Boolean | 无 | - |
| query-form-param | 动态模式 - 请求参数(表格查询参数) | Object | {} | - |
| dataPreprocess | 动态模式 - 云函数返回的数据进行预处理 | function(list) | - | - |
| data | 静态模式 - 列表数据 | Array | 无 | - |
| total | 静态模式 - 总记录数 | Number | 无 | - |
| columns | 通用 - 字段显示规则 | Array | [] | [查看columns](#columns) |
| height | 通用 - table的高度 | Number | 无 | - |
| max-height | 通用 - table的最大高度 | Number | 无 | - |
| row-height | 通用 - 行高 | Number | 无 | - |
| top | 通用 - margin-top的高度 | Number | 10 | - |
| selection | 通用 - 显示多选框 | Boolean | false | true |
| rowNo | 通用 - 显示序号 | Boolean | false | true |
| pagination | 通用 - 显示分页器 | Boolean | false | true |
| page-size | 通用 - 每页显示数量 | Number | 10 | - |
| page-sizes | 通用 - 每页显示数量选择列表 | Array | [1, 5, 10, 20, 50, 100, 1000] | - |
| right-btns | 通用 - 右侧显示的按钮列表 | Array | [] | [查看right-btns](#right-btns) |
| right-btns-type | 通用 - 右侧显示的按钮类型 | String | "button" | "text" |
| right-btns-more | 通用 - 右侧更多按钮 | Array | [] | [查看right-btns-more](#right-btns-more) |
| custom-right-btns | 通用 - 自定义右侧按钮 | Array | [] | [查看custom-right-btns](#custom-right-btns) |
| row-key | 通用 - 行数据的 Key | Function,String | "_id" | - |
| empty-text | 通用 - 空数据时显示的文本内容 | String | "暂无数据" | - |
| default-expand-all | 通用 - 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 | Boolean | false | true |
| tree-props | 通用 - 渲染嵌套数据的配置选项 | Object | {children: 'children', hasChildren: 'hasChildren'} | - |
| border | 通用 - 是否带有纵向边框 | Boolean | false | true |
| stripe | 通用 - 是否为斑马纹 | Boolean | false | true |
| size | 通用 - Table 的尺寸 | String | 无 | medium / small / mini |
| show-header | 通用 - 是否显示表头 | Boolean | true | false |
| highlight-current-row | 通用 - 是否要高亮当前行 | Boolean | true | false |
| detail-dialog-width | 通用 - 详情弹窗的宽度 | Number,String | "830px" | - |
| multiple | 通用 - 可多选 |Boolean | true | false |
| default-sort | 默认排序规则 |Object | - | [查看default-sort](#default-sort) |
| show-summary | 通用 - 是否需要显示合计行 |Boolean | false | true |
| summary-method | 通用 - 自定义合计的计算函数(详情见下方) |Function | - | [查看summary-method](#summary-method) |
| total-option | 通用 - 需要自动统计的行(详情见下方) |Array | - | - |
#### default-sort
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|------------------|-------------------------------|---------|--------|-------|
| name | 需要排序的字段名 | String | - | - |
| type | 排序类型 | String | asc(升序) | desc(降序) |
### 事件
| 事件名 | 说明 | 回调参数 |
|----------|------------------------|------|
| selection-change | 多选框状态发生变化时 | rows |
| current-change | 点击(高亮)某一行 | row |
| row-click | 单击某一行 | row, column, event |
| row-dblclick | 双击某一行 | row, column, event |
| row-contextmenu | 鼠标右键某一行 | row, column, event |
| cell-click | 单击某一个单元格 | row, column, cell, event |
| cell-dblclick | 双击某一个单元格 | row, column, cell, event |
| header-click | 某一列的表头被点击时 | column, event |
| header-contextmenu | 某一列的表头被鼠标右键点击时 | row, btn |
| custom-right-btns | 自定义右侧按钮点击事件 | column, event |
| 其他 | 其他element自带的事件大部分也支持 | - |
### 方法
#### 通过 this.$refs.table1.xxx(); 方式调用
| 方法名 | 说明 |
|----------|------------------------|
| refresh | 刷新 |
| search | 查询(搜索) |
| getCurrentRow | 获取当前选中的行的数据 |
| getTableData | 获取整个表格数据 |
| getMultipleSelection | 获取多选框的数据 |
| showDetail | 显示详情页 |
| closeDetail | 关闭详情页 |
| exportExcel | 导出xls表格文件 |
| deleteRows | 删除指定的行(不删数据库数据) |
| updateRows | 更新指定的行数据(不更新据库数据) |
#### 删除指定的行(不删数据库数据)
```js
that.$refs.table1.deleteRows({
ids:["60acf6248a69dc00018d8520"],
success:function(){
}
});
```
#### 更新指定的行数据(不更新据库数据)
```js
that.$refs.table1.updateRows({
mode:"update", // update 局部字段更新 set 覆盖字段更新
rows:[
{ _id:"60acf6248a69dc00018d8520", remark:"被修改了", money:10000 }
],
success:function(){
}
});
```
#### 导出表格显示的数据
```js
that.$refs.table1.exportExcel();
```
#### 自定义导出表格数据
```js
that.$refs.table1.exportExcel({
fileName : "表格数据",
original : false,
columns: [
{ key:"_id", title:"id", type:"text" },
{ key:"money", title:"金额", type:"money" },
]
});
```
#### 导出自定义数据
```js
that.$refs.table1.exportExcel({
fileName:"文件名称",
data:[
{ a:1,b:2},
{ a:11,b:22}
],
columns:[
{ key:"a", title:"标题a", type:"text" },
{ key:"b", title:"标题b", type:"text" },
]
});
```
### 插槽
#### columns中的每一个key都是插槽的名称
#### 如重写`gender`字段的渲染
```html
{{ row.gender }}
```
### 详细说明
#### columns
#### columns是一个数组,数组内每个元素有以下属性
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|------- |-----------|---------|-------|-------|
| key | 键名 | String | 无 | - |
| title | 标题 | String | 无 | - |
| type | 类型 | String | 无 | [查看type](#type) |
| width | 宽度 | Number | 无 | - |
| minWidth | 最小宽度(设置此值会自动填充宽度) | Number | 无 | - |
| alignt | 对其方式 | String | center | left 、right |
| headerAlign | 表头对其方式 | String | center | left 、right |
| sortable | 是否是排序字段 | String | custom | true 、false |
| fixed | 列是否固定在左侧或者右侧,true 表示固定在左侧 | string, boolean | 无 | true、left、right |
| show | 显示规则,当为"detail" 代表只在详情弹窗时显示,"row" 代表只在表格内显示,"none" 代表均不显示 | string 、 array | ["detail","row"] | "detail"、"row"、"none" |
| defaultValue | 默认值 | String | 无 | - |
| formatter | 自定义格式化函数 | function(val, row, column, index) | - | - |
#### type
#### type(类型)
```js
table1:{
columns:[
{ key: "nickname", title: "昵称", type: "text", width: 120, defaultValue:"未设置昵称", },
{ key: "avatar", title: "头像", type: "avatar", width: 80 },
{ key: "images", title: "图片", type: "image", width: 120 },
{ key: "rate", title: "评分", type: "rate", width: 120 },
{ key: "switch", title: "开关", type: "switch", width: 120 },
{ key: "icon", title: "图标", type: "icon", width: 120 },
{
key: "type", title: "类型", type: "tag", width: 120, size: "mini",
data:[
{ value:1, label:"收入", tagType:"success" },
{ value:2, label:"支出", tagType:"danger" }
]
},
{ key: "_add_time", title: "添加时间", type: "time", width: 160, valueFormat:"yyyy-MM-dd hh:mm:ss" },
{ key: "_add_time", title: "距离现在", type: "dateDiff", width: 120 },
{
key: "nickname", title: "html渲染", type: "html", defaultValue: "未设置",
formatter: function(val, row, column, index) {
let str = `${val}(审核通过)`;
return str;
}
},
{ key: "balance", title: "余额", type: "money", width: 120 },
{ key: "percentage", title: "占比", type: "percentage", width: 120 },
{ key: "address", title: "地址", type: "address", width: 120 },
{ key: "userInfo", title: "用户", type: "userInfo", width: 120 },
{
key: "", title: "分组显示", type: "group", minWidth: 290, align:"left",
columns:[
{ key: "_id", title: "ID", type: "text" },
{ key: "avatar", title: "头像", type: "avatar" },
{ key: "nickname", title: "昵称", type: "text" },
],
},
{
key: "object1", title: "对象字段", type: "object", width: 180, align:"left",
columns:[
{ key: "key1", title: "对象内字段1", type: "text" },
{ key: "key2", title: "对象内字段2", type: "text" },
],
},
{
key: "gender", title: "性别", type: "radio", width: 120, defaultValue:0,
data:[
{ value:1, label:"男" },
{ value:2, label:"女" },
{ value:0, label:"保密" },
]
},
{
key: "gender", title: "性别", type: "select", width: 120, defaultValue:0,
data:[
{ value:1, label:"男" },
{ value:2, label:"女" },
{ value:0, label:"保密" },
]
},
{
key: "checkbox", title: "多选字段", type: "checkbox", width: 120, defaultValue:1,
data:[
{ value: 1, label: "选项1" },
{ value: 2, label: "选项2" },
]
}
]
}
```
#### right-btns
#### right-btns(右侧按钮列表)
```html
```
##### right-btns数组内的可选值有
| 可选值 | 说明 |
|----------|------------------------|
| detail | 点击后触发detail事件 |
| detail_auto | 点击后自动弹出详情页 |
| update | 点击后触发update事件 |
| delete | 点击后触发delete事件 |
| more | 与 rightBtnsMore 搭配使用|
#### right-btns-more
#### right-btns-more(右侧更多按钮点击后显示的按钮列表)
```html
```
```js
data() {
return {
table1:{
rightBtnsMore:[
{
title:'按钮1',
onClick:function(item){
}
},
{
title:'按钮2',
onClick:function(item){
}
}
]
}
}
}
```
#### custom-right-btns
#### custom-right-btns (右侧自定义按钮)
```html
```
```js
methods: {
customRightBtns(item, btn){
}
}
```
### 条件查询
#### 可搭配表格搜索组件`vk-data-table-query` 进行条件查询
```html
```
```js
queryForm1:{
// 查询表单数据源,可在此设置默认值
formData:{
},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns:[
{ key:"nickname", title:"昵称", type:"text", width:160, mode:"%%" },
{ key:"_add_time", title:"添加时间", type:"datetimerange", width:400, mode:"[]" },
]
}
```
#### queryForm1.columns 参数说明
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|------- |-----------|---------|-------|-------|
| key | 键名 | String | 无 | - |
| title | 标题 | String | 无 | - |
| type | 组件类型 | String | 无 | - |
| width | 组件宽度 | Number | 无 | - |
| placeholder | 输入前的提示 | String | - | - |
| mode | 查询模式 | String | = | [查看mode](#mode) |
| fieldName | 数据库字段名称,默认=key的值 | String | key的值 | - |
| lastWhereJson | 是否是连表后的where条件 | Boolean | false | true |
#### fieldName 参数的用处
##### 如余额按金额范围查询
```js
columns:[
{
key:"balance1", title:"金额范围", type:"money", width:160, placeholder:"请输入最小金额",
mode:">=", fieldName:"balance",
},
{
key:"balance2", title:"-", type:"money", width:160, placeholder:"请输入最大金额",
mode:"<=", fieldName:"balance",
}
]
```
#### lastWhereJson 参数的用处
##### 如userInfo是连表字段的as的值,想要根据 userInfo.mobile 进行查询
```js
columns:[
{
key:"mobile", title:"手机号", type:"text", width:160,
mode:"=", fieldName:"userInfo.mobile", lastWhereJson:true
}
]
```
#### mode
#### queryForm1.columns 中 mode 参数详情
| 值 | 说明
|------------|-------------------|
| = | 完全匹配 |
| != | 不等于 |
| %% | 模糊匹配 |
| %* | 以xxx开头 |
| *% | 以xxx结尾 |
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| in | 在数组里 |
| nin | 不在数组里 |
| [] | 范围 arr[0] <= x <= arr[1] |
| [) | 范围 arr[0] <= x < arr[1]|
| (] | 范围 arr[0] < x <= arr[1] |
| () | 范围 arr[0] < x < arr[1] |
#### 万能表格合计列的示例
#### 简单模式
```html
```
#### summary-method
#### 万能表格合计列的示例
#### 自定义函数方法,如果涉及到金额,则需要使用summary-method属性进行自定义,代码如下
```html
```
```js
summaryMethod({ columns, data }) {
const means = ['']; // 合计
// 需要进行合计的字段
let totalOption = [
{ key: 'money', 'unit': '元', type:"money" },
];
for(let columnIndex=0; columnIndex Number(dataItem[column.property]));
// 合计
if (!values.every(value => isNaN(value))) {
means[columnIndex] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
if(columnItem.type === "money"){
// 金额字段的特殊处理
let money = vk.pubfn.priceFilter(means[columnIndex]);
means[columnIndex] = `${money}${columnItem.unit}`;
}else{
means[columnIndex] = `${means[columnIndex]}${columnItem.unit}`;
}
} else {
// 如果不是数字类型,则直接为空
means[columnIndex] = "";
}
}
}
return [means];
}
```