示例
数据表格快捷键
仅在 selectable 情况下支持
- 上下方向键切换行,需要手动选中一行
- 高亮行回车默认触发 enter 事件,
- 空格键当前行选中或者取消选中
静态数据
<page>
<table data="{{tableData}}" height="auto">
<x-cell label="日期">
{{cellData.rowData.date}}
</x-cell>
<x-cell label="姓名">
{{cellData.rowData.name}}
</x-cell>
<x-cell label="地址">
{{cellData.rowData.address}}
</x-cell>
</table>
</page>
export default XPage({
data: {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
});
数据趋势
<page>
<table data="{{tableData}}" height="auto">
<x-cell label="上升趋势(chartup)">
<x-datacell type="chartup" :data="cellData.rowData.chartup"/>
</x-cell>
<x-cell label="下降趋势(chartdown)">
<x-datacell type="chartdown" :data="cellData.rowData.chartdown"/>
</x-cell>
<x-cell label="条形图(bar)">
<x-datacell type="bar" :data="cellData.rowData.bar"/>
</x-cell>
<x-cell label="圆环(cycle)">
<x-datacell type="cycle" :data="cellData.rowData.cycle"/>
</x-cell>
</table>
</page>
export default XPage({
data: {
tableData: [
{
chartup:'80',
chartdown:'80',
bar:'80',
cycle:'80',
},
{
chartup:'70',
chartdown:'70',
bar:'70',
cycle:'70',
},
{
chartup:'60',
chartdown:'60',
bar:'60',
cycle:'60',
}
]
}
});
x-datacell
标签支持在表格内展示数据趋势,type
支持chartup
chartdown
bar
cycle
四种类型 data
值为数字,目前仅建议使用在table内
左右吸附
<page>
<x-table data="{{tableData}}" height="200px">
<x-cell label="No." fixed="left">
{{cellData.rowIndex+1}}
</x-cell>
<x-cell label="日期">
{{cellData.rowData.date}}
</x-cell>
<x-cell label="姓名">
{{cellData.rowData.name}}
</x-cell>
<x-cell label="省/直辖市">
{{cellData.rowData.province}}
</x-cell>
<x-cell label="市区">
{{cellData.rowData.city}}
</x-cell>
<x-cell label="详细地址">
{{cellData.rowData.address}}
</x-cell>
<x-cell label="邮编">
{{cellData.rowData.zip}}
</x-cell>
<x-cell label="学历">
{{cellData.rowData.education}}
</x-cell>
<x-cell label="职业">
{{cellData.rowData.occupation}}
</x-cell>
<x-cell label="操作" fixed="right">
<x-button text="编辑"></x-button>
<x-button text="操作"></x-button>
</x-cell>
</x-table>
</page>
export default XPage({
data: {
tableData: [{
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-08',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-06',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-07',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-08',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-06',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-07',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}]
}
});
selectable 可选择
<page>
<x-button text="选中第一个" bindclick="choose(0)"></x-button>
<x-button text="选中最后个" bindclick="choose(13)"></x-button>
<x-button text="获取选中数据" bindclick="showSelect"></x-button>
<x-table x="table" :data="tableData" height="200px" selectable>
<x-cell label="No." fixed="left">
{{cellData.rowIndex+1}}
</x-cell>
<x-cell label="日期">
{{cellData.rowData.date}}
</x-cell>
<x-cell label="姓名">
{{cellData.rowData.name}}
</x-cell>
<x-cell label="省/直辖市">
{{cellData.rowData.province}}
</x-cell>
<x-cell label="市区">
{{cellData.rowData.city}}
</x-cell>
<x-cell label="详细地址">
{{cellData.rowData.address}}
</x-cell>
<x-cell label="邮编">
{{cellData.rowData.zip}}
</x-cell>
<x-cell label="学历">
{{cellData.rowData.education}}
</x-cell>
<x-cell label="职业">
{{cellData.rowData.occupation}}
</x-cell>
<x-cell label="操作" fixed="right">
<x-button text="编辑"></x-button>
<x-button text="操作"></x-button>
</x-cell>
</x-table>
</page>
export default XPage({
data: {
tableData: [{
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-08',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-06',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-07',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-08',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-06',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}, {
date: '2016-05-07',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: "前端工程师"
}]
},
choose(num) {
this.getComponent('table').select(num);
},
showSelect() {
const data = this.getComponent('table').getData();
console.log('打开控制台产看当前数据', data);
let [first] = data.selected;
alert(`当前选中行${++first}`);
}
});
selectable 默认选中
<page class="demo-box">
<x-button text="重置" bindclick="refresh"></x-button>
<x-table key="{{tableKey}}" x="table" data="{{tableData}}" height="200px" selectable="{{multiple:true}}" bindrendered=tableRendered beforeRequest="{{beforeRequest}}">
<x-cell label="No." fixed="left">
{{cellData.rowIndex+1}}
</x-cell>
<x-cell label="日期">
{{cellData.rowData.date}}
</x-cell>
<x-cell label="姓名">
{{cellData.rowData.name}}
</x-cell>
<x-cell label="省/直辖市">
{{cellData.rowData.province}}
</x-cell>
<x-cell label="市区">
{{cellData.rowData.city}}
</x-cell>
<x-cell label="详细地址">
{{cellData.rowData.address}}
</x-cell>
<x-cell label="邮编">
{{cellData.rowData.zip}}
</x-cell>
<x-cell label="学历">
{{cellData.rowData.education}}
</x-cell>
<x-cell label="职业">
{{cellData.rowData.occupation}}
</x-cell>
<x-cell label="操作" fixed="right">
<x-button text="编辑"></x-button>
<x-button text="操作"></x-button>
</x-cell>
<actions>
<button text="删除"></button>
</actions>
</x-table>
</page>
export default XPage({
data: {
tableKey: new Date().getTime(),
tableData: [
{
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-08',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-06',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-07',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-08',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-06',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
{
date: '2016-05-07',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
education: '本科',
occupation: '前端工程师',
},
],
},
tableRendered() {
this.getComponent('table').select([1, 2, 4]);
this.getComponent('table').select({
rowNum: 3,
attrs: {
disabled: true,
},
});
},
beforeRequest(params) {
return params;
},
refresh() {
this.tableKey = new Date().getTime();
},
});
表格行上下移
<page class="demo-box">
<form type="search" confirm-button bindconfirm="search">
<item label="姓名" node="input" name="name"></item>
<item label="学历" node="select" data="{{educations}}" name="education"></item>
</form>
<table
x="table"
height="300px"
type="super"
pageable="{{ pageSize: 20 }}"
ajax="{{ajax}}"
selectable="{{multiple: true,beforeRenderCheckbox}}"
>
<toolbar>
<button icon="x-icon-action-move_up" bindclick="handleMove(-1)" />
<button icon="x-icon-action-move_down" bindclick="handleMove(1)" />
</toolbar>
<cell label="No." name="rowNO" :visible="true" fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期" name="date" :visible="false">
{{cellData.rowData.date}}
</cell>
<cell
dm-for="(column, index) in columns"
key="{{column.name}}"
name="{{column.name}}"
label="{{column.label}}"
tips="{{column.tips}}"
>
{{cellData.rowData[column.name]}}
</cell>
<cell label="详细地址" name="address" :visible="true">
{{cellData.rowData.address}}
</cell>
<cell label="邮编" name="zip" :visible="false">
{{cellData.rowData.zip}}
</cell>
<cell label="学历" name="education" :visible="false">
{{cellData.rowData.education}}
</cell>
<cell label="职业" name="occupation" :visible="false">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
function fetchMockColumns() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([
{
label: '姓名',
name: 'name',
tips: '姓名',
},
{
label: '省/直辖市',
name: 'province',
tips: '省/直辖市',
},
{
label: '市区',
name: 'city',
tips: '市区',
},
]);
}, 80);
});
}
export default XPage({
data: {
ajax: {
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
},
educations: [],
wareType: 1,
columns: [],
},
show() {
this.init();
},
init() {
this.setData({
educations: [
{ label: '全部', value: '' },
{ label: '大专', value: '大专' },
{ label: '本科', value: '本科' },
],
});
fetchMockColumns().then((res) => {
this.setData({
columns: res,
});
});
},
search(value) {
const table = this.getComponent('table');
table.query({ params: value });
},
handleEdit(name) {
CabinX.alert({
title: '编辑',
text: `${name}Edit`,
});
},
handleOper(name) {
CabinX.alert({
title: '操作',
text: `${name}Oper`,
});
},
handleMove(offset) {
const table = this.getComponent('table');
const selected = table.getData().selected || [];
const hasSelected = !!selected.length;
if (hasSelected) {
table.moveRows(selected, offset);
}
},
beforeRenderCheckbox({rowData, rowIndent, rowIndex}) {
if ([1,3,4].includes(rowIndex)){
return {
disabled: true
}
}
return true
},
});
本地分页
<page>
<table data="{{tableData}}" height="auto" pageable="{{pageSize:10}}">
<x-cell label="日期">
{{cellData.rowData.date}}
</x-cell>
<x-cell label="姓名">
{{cellData.rowData.name}}
</x-cell>
<x-cell label="地址">
{{cellData.rowData.address}}
</x-cell>
</table>
</page>
export default XPage({
data: {
tableData: null
},
show(){
let self = this;
setTimeout(()=>{
self.setData({
tableData:tableData
})
},2000)
}
});
let tableData = [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
},{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
异步数据渲染
注意:许多使用过cabin2.0的小伙伴都清楚,一个有分页功能的表格,是通过表格组件,分页组件实现交互,请求数据的逻辑和分页的逻辑由研发自己编写实现的。
在cabinx中,我们简化了这个的实现复杂度,你只需提供请求的相关参数(如url,业务参数),和了解这个插件所需要的数据格式。
ajax类型为对象
<page class="demo-box">
<form type="search" confirm-button bindconfirm="search">
<item label="姓名" node="input" name="name"></item>
<item label="学历" node="select" data="{{educations}}" name="education"></item>
</form>
<table
x="table"
height="300px"
pageable="{{ pageSize: 10 }}"
ajax="{{ajax}}"
beforeRequest="{{beforeRequest2}}"
beforeRender="{{beforeRender}}"
bind-rendered="handleRendered"
>
<tag slot="caption" text="DBA人数:{{dbaCount}}"></tag>
<cell label="No." fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期">
{{cellData.rowData.date}}
</cell>
<cell label="姓名">
{{cellData.rowData.name}}
</cell>
<cell label="省/直辖市">
{{cellData.rowData.province}}
</cell>
<cell label="市区">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址">
{{cellData.rowData.address}}
</cell>
<cell label="邮编">
{{cellData.rowData.zip}}
</cell>
<cell label="学历">
{{cellData.rowData.education}}
</cell>
<cell label="职业">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
export default XPage({
data: {
ajax: {
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
},
educations: [],
dbaCount: 0,
},
show() {
this.init();
},
init() {
this.setData({
educations: [
{ label: '全部', value: '' }, { label: '大专', value: '大专' }, { label: '本科', value: '本科' }
],
});
},
search(value) {
const table = this.getComponent('table');
table.query({ params: value });
},
handleEdit(name) {
CabinX.alert({
title: '编辑',
text: `${name}Edit`,
});
},
handleOper(name) {
CabinX.alert({
title: '操作',
text: `${name}Oper`
});
},
/**
* 接口请求前,自定义入参
* @param {Object} args
* @param {Array} sorts 表格列排序字段
*/
beforeRequest(params, sorts) {
const newParams = params;
const surname = '李';
// 李氏三亚人 demo
if ((params.name || '').indexOf(surname) !== -1) {
Object.assign(newParams, { city: '三亚市' });
}
this.setData({
tableStatus: 'loading',
});
return newParams;
},
/**
* 接口数据返回后,自定义返回数据
* @param {Object} res
* @returns
*/
beforeRender(res) {
/*姓名脱敏 */
res.data.result = res.data.result.map(item => {
const { name, ...rest } = item;
const first = name.slice(0, 1);
const finalName = name.length <= 2
? first.padEnd(name.length, '*')
: `${first}${name.slice(-1).padStart(name.length - 1, '*')}`;
return { name: finalName, ...rest };
});
return res;
},
/**
* 表格rendered (渲染完成)listener
*/
handleRendered({ data }) {
this.setData({
dbaCount: data.reduce((acc, cur) => acc + (cur.occupation === 'DBA' ? 1 : 0), 0),
});
},
beforeRequest2(data){
delete data.name;
return data;
},
});
ajax类型为Promise
<page class="demo-box">
<head>
<form type="search" confirm-button bindconfirm="search">
<item label="姓名" node="input" name="name"></item>
<item label="学历" node="select" data="{{educations}}" name="education"></item>
</form>
</head>
<main>
<table
x="table"
pageable
ajax="{{fetchData}}"
beforeRequest="{{beforeRequest}}"
>
<cell label="No." fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期">
{{cellData.rowData.date}}
</cell>
<cell label="姓名">
{{cellData.rowData.name}}
</cell>
<cell label="省/直辖市">
{{cellData.rowData.province}}
</cell>
<cell label="市区">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址">
{{cellData.rowData.address}}
</cell>
<cell label="邮编">
{{cellData.rowData.zip}}
</cell>
<cell label="学历">
{{cellData.rowData.education}}
</cell>
<cell label="职业">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</main>
</page>
export default XPage({
props: {
ajaxIsFunc: {
type: Boolean,
default: false,
}
},
data: {
educations: [],
},
show() {
this.init();
},
init() {
this.setData({
educations: [
{ label: '全部', value: '' }, { label: '大专', value: '大专' }, { label: '本科', value: '本科' }
],
});
},
search(value) {
const table = this.getComponent('table');
table.query({ params: value });
},
handleEdit(name) {
CabinX.alert({
title: '编辑',
text: `${name}Edit`,
});
},
handleOper(name) {
CabinX.alert({
title: '操作',
text: `${name}Oper`
});
},
/**
* 接口请求前,自定义入参
* @param {Object} args
* @param {Array} sorts 表格列排序字段
*/
beforeRequest(params, sorts) {
let newParams = params;
// 编辑参数
newParams.custom = '大幅度发';
return newParams;
},
fetchData(params) {
return CabinX.ajax({ withCredentials: true }).get({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
params,
});
},
});
表格自定义列
自定义列展示需要依赖 cell 标签上的 visible 和 name 属性, 且visible 属性必须是 布尔值, 本地自定义存储
<page class="demo-box">
<form type="search" confirm-button bindconfirm="search">
<item label="姓名" node="input" name="name"></item>
<item label="学历" node="select" data="{{educations}}" name="education"></item>
</form>
<table
x="table"
height="500px"
pageable="{{ pageSize: 10 }}"
ajax="{{ajax}}"
selectable="{{selectable}}"
@column-changed="tableFilterChange"
:columnSettable="columnSettable"
>
<radio slot="caption" class="fix-radio-button" x="radio" value="{{wareType}}" data="{{[{label:'推荐商品',value:1},{label:'更多商品',value:2}]}}" display-type="button" bindchanged="handleWareTypeChage"></radio>
<toolbar
data="{[
{ name: 'export' },
{ name: 'print' },
{ name: 'download'},
]}"
bindtool-click="handleToolClick"
>
<button text="打印跨页选择结果" bindclick="showMultipageSelected" />
<button icon="x-icon-action-move_up" bindclick="handleMove(-1)" />
<button icon="x-icon-action-move_down" bindclick="handleMove(1)" />
</toolbar>
<cell label="No." name="rowNO" :visible="true" fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期" name="date" :visible="false">
{{cellData.rowData.date}}
</cell>
<cell
dm-for="(column, index) in columns"
key="{{column.name}}"
name="{{column.name}}"
label="{{column.label}}"
tips="{{column.tips}}"
>
{{cellData.rowData[column.name]}}
</cell>
<cell label="详细地址" name="address" :visible="true">
{{cellData.rowData.address}}
</cell>
<cell label="邮编" name="zip" :visible="false">
{{cellData.rowData.zip}}
</cell>
<cell label="学历" name="education" :visible="false">
{{cellData.rowData.education}}
</cell>
<cell label="职业" name="occupation" :visible="false">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
function fetchMockColumns() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([
{
label: '姓名',
name: 'name',
tips: '姓名',
},
{
label: '省/直辖市',
name: 'province',
tips: '省/直辖市',
},
{
label: '市区',
name: 'city',
tips: '市区',
},
]);
}, 80);
});
}
export default XPage({
data: {
ajax: {
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
},
educations: [],
wareType: 1,
columnSettable: {
draggable: true, // 可以拖动
persist: true,
tips: '自定义列',
},
columns: [],
selectable: {
multiple: true,
multipage: true,
valueKey: 'name',
labelKey: 'name',
initialMultipageSelected: [
{ value: '范杰', label: '范杰' },
{ value: '邹涛', label: '邹涛' },
],
},
},
show() {
this.init();
},
init() {
this.setData({
educations: [
{ label: '全部', value: '' },
{ label: '大专', value: '大专' },
{ label: '本科', value: '本科' },
],
});
fetchMockColumns().then((res) => {
this.setData({
columns: res,
});
});
},
search(value) {
const table = this.getComponent('table');
table.query({ params: value });
},
handleEdit(name) {
CabinX.alert({
title: '编辑',
text: `${name}Edit`,
});
},
handleOper(name) {
CabinX.alert({
title: '操作',
text: `${name}Oper`,
});
},
handleToolClick(tool) {
const { name } = tool;
console.log('tool ', tool);
},
// 表格列的变动后会触发这个方法(拖动、展示、隐藏、pin)
tableFilterChange(data = []) {
const fields = [];
data.forEach((item) => {
// 表格cell 上设置了名称 并且 visible 是ture 就代表是显示
if (item.visible !== false && item.name) {
fields.push(item.name);
}
});
console.log('tableFilterChange: ', fields);
return fields;
},
handleWareTypeChage(wareType) {
this.setData({
wareType,
});
console.log('handleWareTypeChage:', this.data.wareType);
},
handleMove(offset) {
const table = this.getComponent('table');
const [rowIndex] = table.getData().selected || [];
if (rowIndex) {
table.moveRow(+rowIndex, +rowIndex + offset);
}
},
showMultipageSelected() {
const selected = this.getComponent('table').getMultipageSelected();
console.log('multipageSelected', selected);
}
});
自定义列可以通过columnSettable.initialColumns初始,适应于后端保存自定义列配置。
<page class="demo-box">
<form type="search" confirm-button bindconfirm="search">
<item label="姓名" node="input" name="name"></item>
<item label="学历" node="select" data="{{educations}}" name="education"></item>
</form>
<table
x="table"
height="300px"
title="自定义表格列"
pageable="{{ pageSize: 10 }}"
ajax="{{ajax}}"
selectable
@column-changed="tableFilterChange"
:columnSettable="columnSettable"
>
<cell label="No." name="rowNO" fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期" name="date">
{{cellData.rowData.date}}
</cell>
<cell label="姓名" name="name">
{{cellData.rowData.name}}
</cell>
<cell label="省/直辖市" name="province">
{{cellData.rowData.province}}
</cell>
<cell label="市区" name="city">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址" name="address">
{{cellData.rowData.address}}
</cell>
<cell label="邮编" name="zip">
{{cellData.rowData.zip}}
</cell>
<cell label="学历" name="education">
{{cellData.rowData.education}}
</cell>
<cell label="职业" name="occupation">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
function fetchMockColumns() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([
{ name: 'name', visible: true, fixed: 'content' },
{ name: 'date', visible: true, fixed: 'content' },
{ name: 'province', visible: false, fixed: 'content' },
{ name: 'city', visible: false, fixed: 'content' },
{ name: 'address', visible: false, fixed: 'content' },
{ name: 'zip', visible: true, fixed: 'content' },
{ name: 'education', visible: true, fixed: 'content' },
{ name: 'occupation', visible: true, fixed: 'content' },
]);
}, 100);
});
}
export default XPage({
data: {
ajax: {
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
},
educations: [],
wareType: 1,
columnSettable: {
draggable: true, // 可以拖动
persist: false,
tips: '自定义列',
initialColumns: [],
},
},
show() {
this.init();
},
init() {
this.setData({
educations: [
{ label: '全部', value: '' }, { label: '大专', value: '大专' }, { label: '本科', value: '本科' }
],
});
this.initTaleColumns();
},
initTaleColumns() {
// 可通过ajax调用后端接口初始化列的数据
fetchMockColumns().then(columns => {
this.setData({
'columnSettable.initialColumns': columns,
});
});
},
search(value) {
const table = this.getComponent('table');
table.query({ params: value });
},
handleEdit(name) {
CabinX.alert({
title: '编辑',
text: `${name}Edit`,
});
},
handleOper(name) {
CabinX.alert({
title: '操作',
text: `${name}Oper`
});
},
handleToolClick(tool) {
const { name } = tool;
console.log('tool ', tool);
},
// 表格列的变动后会触发这个方法(拖动、展示、隐藏、pin)
tableFilterChange(data = []) {
const fields = [];
data.forEach((item) => {
// 表格cell 上设置了名称 并且 visible 是ture 就代表是显示
if (item.visible !== false && item.name) {
fields.push(item.name)
}
})
console.log('tableFilterChange: ', fields)
return fields
},
handleWareTypeChage(wareType) {
this.setData({
wareType
});
console.log('handleWareTypeChage:', this.data.wareType);
},
handleMove(offset) {
const table = this.getComponent('table');
const [rowIndex] = table.getData().selected || [];
if (rowIndex) {
table.moveRow(+rowIndex, +rowIndex + offset);
}
},
});
表格下钻(树形数据)
当rowData中含children属性时, 将按照树进行渲染。如果ajax返回的行数据不包含children属性可以通过beforeRender方法增加。
<page>
<table
height="auto"
bordered
summary="{{summary}}"
ajax="//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/children"
beforeRender="{{beforeRender}}"
bind-rendered="handleTableRendered"
>
<cell label="采销部类">
{{cellData.rowData.aggName}}
</cell>
<cell label="采销部类编码">
{{cellData.rowData.aggCode}}
</cell>
<cell label="库商品" name="sex">
{{cellData.rowData.zeroStockCount}}
</cell>
<cell label="畅缺商品">
{{cellData.rowData.lackStockCount}}
</cell>
<cell label="总店品项数">
{{cellData.rowData.allCount}}
</cell>
<cell label="缺货率">
{{cellData.rowData.stockoutRate}}
</cell>
<cell label="主数据" align="right">
<button text="{{String(cellData.rowData.mainDataExceptionNum)}}" type="link" />
</cell>
<cell label="门店" align="right">
<button text="{{String(cellData.rowData.storeNum)}}" type="link" />
</cell>
<cell label="供应商" align="right">
<button text="{{String(cellData.rowData.purchaseNum)}}" type="link" />
</cell>
</table>
</page>
export default XPage({
data: {
sex: [{value: '男', label: '男'}, {value: '女', label: '女'}],
summary: {
data: []
}
},
beforeRender(res) {
const traverse = (list) => {
return list.map(item => {
const {childList, ...rest} = item;
return {
...rest,
children: childList ? traverse(childList) : null
};
});
}
res.data.result = traverse(res.data.result);
return res;
},
handleTableRendered({data}) {
if (!data || !data.length) {
return;
}
const fields = [
['aggCode', ''],
['zeroStockCount', 0],
['lackStockCount', 0],
['allCount', 0],
['stockoutRate', ''],
['mainDataExceptionNum', 0],
['storeNum', 0],
['purchaseNum', 0]
];
let label = '总计:';
const summaryData = data.reduce((acc, cur) => {
const {aggParentCode} = cur;
if (aggParentCode != null) {
return {label, value: acc};
}
fields.forEach((field, index) => {
const [key, value] = field;
if (typeof value === 'number') {
let val = acc[ index ] ? ( acc[ index ].value!==undefined ? acc[ index ].value : acc[ index ] ) : 0
acc[ index ] = {
label,
value: val + ( cur[ key ] || 0 )
}
}
});
return acc;
}, []);
setTimeout(()=>{
this.setData({
'summary.data': summaryData
});
},5000)
}
});
表格下钻(数据异步加载)
通过tree-props属性设置加载下钻数据的函数和是否包含下钻数据的属性名
<page>
<table
x="table"
height="auto"
bordered
row-key="aggCode"
tree-props="{{ hasChildrenKey: 'hasChild', load: loadChildRows }}"
summary="{{summary}}"
ajax="{{fetchData}}"
beforeRender="{{beforeRender}}"
bind-rendered="handleTableRendered"
>
<cell label="采销部类">
{{cellData.rowData.aggName}}
</cell>
<cell label="采销部类编码">
{{cellData.rowData.aggCode}}
</cell>
<cell label="库商品" name="sex">
{{cellData.rowData.zeroStockCount}}
</cell>
<cell label="畅缺商品">
{{cellData.rowData.lackStockCount}}
</cell>
<cell label="总店品项数">
{{cellData.rowData.allCount}}
</cell>
<cell label="缺货率">
{{cellData.rowData.stockoutRate}}
</cell>
<cell label="主数据" align="right">
<button text="{{String(cellData.rowData.mainDataExceptionNum)}}" type="link" />
</cell>
<cell label="门店" align="right">
<button text="{{String(cellData.rowData.storeNum)}}" type="link" />
</cell>
<cell label="供应商" align="right">
<button text="{{String(cellData.rowData.purchaseNum)}}" type="link" />
</cell>
</table>
</page>
function fetchTreeTableData(params = {}) {
return CabinX.ajax({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/children/lazy',
method: 'get',
params,
});
}
function traverse(list) {
return list.map(item => {
const { leaf, ...rest } = item;
return {
...rest,
hasChild: leaf === false,
};
});
}
export default XPage({
data: {
sex: [{ value: '男', label: '男' }, { value: '女', label: '女' }],
summary: {
data: []
}
},
beforeRender(res) {
return res;
},
handleTableRendered({ data }) {
if (!data || !data.length) {
return;
}
const fields = [
['aggCode', ''],
['zeroStockCount', 0],
['lackStockCount', 0],
['allCount', 0],
['stockoutRate', ''],
['mainDataExceptionNum', 0],
['storeNum', 0],
['purchaseNum', 0]
];
let label = '总计:';
const summaryData = data.reduce((acc, cur) => {
const { aggParentCode } = cur;
if (aggParentCode != null) {
return { label, value: acc };
}
fields.forEach((field, index) => {
const [key, value] = field;
if (typeof value === 'number') {
let val = acc[index] ? (acc[index].value !== undefined ? acc[index].value : acc[index]) : 0
acc[index] = {
label,
value: val + (cur[key] || 0)
}
}
});
return acc;
}, []);
setTimeout(() => {
this.setData({
'summary.data': summaryData
});
}, 5000);
this.getComponent('table').expandRow('AH01');
},
fetchData(params) {
return fetchTreeTableData(params);
},
loadChildRows(rowData, callback) {
const { aggCode: parentId } = rowData || {};
return fetchTreeTableData({
parentId,
}).then(({ data }) => {
callback(data.result);
});
}
});
行列合并
通过设置cell的属性span定义行列合并,当值为字符串'same'时,跨行合并值相同的单元格;为函数时自定义合并规则
<page class="demo-box">
<!--dm-if=false 改元素将不会创建-->
<module title="表格行列合并" foldable dm-if="false">
<actions>
<button text="详情" icon="x-icon-action-edit-log" no-bordered status="primary"></button>
</actions>
<main>
测试一下
</main>
</module>
<table
x="table"
height="auto"
data="{{tableData}}"
span="{{calcSpan}}"
>
<cell label="姓名1" fixed="left" width="150px" name="name" align="center" sortable sublabel="我的姓名" span="same">
<actions>
<button text="功能" />
</actions>
{{cellData.rowData.name}}
</cell>
<cell label="性别" name="sex">
<cell label="男性">
<cell label="男性1" width="100px" name="sex" span="same">
<cell label="男性1.1" width="100px" name="sex" span="same">
{{cellData.rowData.sex}}
</cell>
</cell>
<cell label="男性2" width="100px" name="sex">
{{cellData.rowData.sex}}
</cell>
<cell label="男性3" width="100px" name="sex" sortable>
{{cellData.rowData.sex}}
</cell>
</cell>
<cell label="女性" width="120px">
{{cellData.rowData.sex}}
</cell>
<cell label="未知" width="120px" align="center">
{{cellData.rowData.sex}}
</cell>
</cell>
<cell label="电话号码" name="phone" width="150px" align="right" sortable>
{{cellData.rowData.phone}}
</cell>
<cell label="出生时辰">
<cell label="出生日期" name="birthDate" width="150px" sortable>
{{cellData.rowData.birthDate}}
</cell>
<cell label="出生时间" name="birthTime" width="150px" sortable>
{{cellData.rowData.birthTime}}
</cell>
</cell>
<cell label="出生地址2" name="birthAddress" width="150px" span="same">
{{cellData.rowData.birthAddress}}
</cell>
<cell label="操作" name="operation" width="200px" fixed>
<button status="primary" no-bordered text="编辑" @click="handleClick"></button>
<button status="primary" no-bordered text="删除" danger @click="handleClick('del', cellData.rowData)"></button>
<button status="primary" no-bordered text="修改门店" @click="handleClick('del', cellData.rowData)"></button>
<button status="primary" no-bordered text="删除门店" @click="handleClick('del', cellData.rowData)"></button>
</cell>
</table>
</page>
function moment(value) {
const timestamp = Date.parse(value);
const isValid = !isNaN(timestamp);
const date = new Date(timestamp);
return {
toDate() {
return date;
},
format(template) {
if (!isValid) {
return String(value);
}
const units = {
'YYYY': () => date.getFullYear(),
'MM': () => date.getMonth() + 1,
'DD': () => date.getDate(),
'HH': () => date.getHours(),
'mm': () => date.getMinutes(),
'ss': () => date.getSeconds(),
}
return template.replace(/\b(\w+)/g, ($0, $1) => {
const unit = units[$1];
if (!unit) {
return '';
}
const ret = String(unit());
return ret.padStart($1.length, '0');
});
},
isValid,
};
}
export default XPage({
data: {
sex: [{ value: '男', label: '男' }, { value: '女', label: '女' }],
tableData: [{
id: '000',
name: '王大虎',
sex: '男',
birthAddress: '地址1',
phone: 13688339329,
birthDate: moment('1990-2-1').toDate(),
birthTime: moment('1990-1-1 12:13:00').toDate()
}, {
id: '001',
name: '王大虎',
sex: '男',
birthAddress: '地址1',
phone: 13688339329,
birthDate: moment('1990-1-1').toDate(),
birthTime: moment('1990-1-1 12:13:00').toDate()
}, {
id: '002',
name: '王二虎',
sex: '男',
birthAddress: '地址2',
phone: 13688339329,
birthDate: moment('1990-1-1').toDate(),
birthTime: moment('1999-1-1 01:13:00').toDate()
}, {
id: '003',
name: '王三虎',
sex: '男',
birthAddress: '地址3',
phone: 13688339329,
birthDate: moment('1980-1-1').toDate(),
birthTime: moment('1980-1-1 18:13:00').toDate()
}, {
id: '004',
name: '王四虎',
sex: '男',
birthAddress: '地址4',
phone: 13688339329,
birthDate: moment('1994-1-1').toDate(),
birthTime: moment('1994-1-1 20:13:00').toDate()
},
{
id: '005',
name: '王四虎',
sex: '男',
birthAddress: '地址4',
phone: 13688339329,
birthDate: moment('1994-1-1').toDate(),
birthTime: moment('1994-1-1 20:13:00').toDate()
}].map(({ birthDate, birthTime, ...rest }) => {
return {
...rest,
birthDate: moment(birthDate).format('YYYY-MM-DD'),
birthTime: moment(birthTime).format('HH:mm:ss'),
};
}),
submitData: {},
},
handleClick() {
},
calcSpan({ rowIndex, columnIndex, row, column }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 3) {
return { rowspan: 1, colspan: 2 };
} else if (columnIndex === 4) {
return { rowspan: 0, colspan: 0 };
}
}
},
});
表格排序
通过设置cell的属性sortable和name开启列排序功能,可以通过initialSorts属性设置默认排序信息,ajax获取数据时,默认通过字段sort带上排序信息,调用后端的接口返回已排序的数据。如需自定义该字段的key和value,可在beforeRequest中定义排序字段信息。针对表格的数据通过data属性绑定的场景,可以前端排序,通过监听sort事件获取排序信息,按照业务场景自行排序。
后端排序
<page class="demo-box">
<head>
<form type="search" confirm-button bindconfirm="search">
<item label="姓名111" node="input" name="name"></item>
<item label="学历222" node="select" data="{{educations}}" name="education"></item>
</form>
</head>
<main>
<table
x="table"
sortMultiple
ajax="{{ajax}}"
pageable="{{ pageSize: 10 }}"
bindsort="handleTableSorted"
initialSorts="{{initialSorts}}"
beforeRequest="{{beforeTableRequest}}"
>
<cell label="No." name="rowNO" fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期" name="date" sortable>
{{cellData.rowData.date}}
</cell>
<cell label="姓名" name="name" sortable>
{{cellData.rowData.name}}
</cell>
<cell label="省/直辖市" name="province">
{{cellData.rowData.province}}
</cell>
<cell label="市区" name="city">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址" name="address">
{{cellData.rowData.address}}
</cell>
<cell label="邮编" name="zip">
{{cellData.rowData.zip}}
</cell>
<cell label="学历" name="education">
{{cellData.rowData.education}}
</cell>
<cell label="职业" name="occupation">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</main>
</module>
</page>
export default XPage({
data: {
ajax: {
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
},
educations: [],
columnSettable: {
draggable: true, // 可以拖动
persist: true,
tips: '自定义列'
},
initialSorts: [
{ name: 'name', order: 'asc' }, // order: 'desc' | 'asc',
],
},
show() {
this.init();
},
init() {
this.setData({
educations: [
{ label: '全部', value: '' }, { label: '大专', value: '大专' }, { label: '本科', value: '本科' }
],
});
},
search(value) {
const table = this.getComponent('table');
table.query({ params: value });
},
handleEdit(name) {
CabinX.alert({
title: '编辑',
text: `${name}Edit`,
});
},
handleTableSorted(sortParams) {
console.log('sortParams', sortParams);
},
beforeTableRequest(params, sortParams) {
const sortInfo = sortParams.map((item) => {
const { name, order } = item;
return `${name}|${order}`;
}).join(',');
return {
...params,
sort: sortInfo,
};
},
});
前端排序
<page>
<head>
<form type="search" confirm-button bindconfirm="search">
<item label="姓名" node="input" name="name"></item>
<item label="学历" node="select" data="{{educations}}" name="education"></item>
</form>
</head>
<main>
<table
x="table"
type="super"
pageable="{{ pageSize: 20 }}"
data="{{tableData}}"
bindsort="handleTableSort"
>
<cell label="No." name="rowNO" fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="姓名" name="name">
{{cellData.rowData.name}}
</cell>
<cell label="出生日期" name="date" sortable>
{{cellData.rowData.date}}
</cell>
<cell label="省/直辖市" name="province">
{{cellData.rowData.province}}
</cell>
<cell label="市区" name="city">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址" name="address">
{{cellData.rowData.address}}
</cell>
<cell label="邮编" name="zip">
{{cellData.rowData.zip}}
</cell>
<cell label="学历" name="education">
{{cellData.rowData.education}}
</cell>
<cell label="职业" name="occupation">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEditRow(cellData.rowData)"></button>
<button text="删除" bindclick="handleDeleteRow(cellData.rowData, cellData.rowIndex)"></button>
</cell>
</table>
</main>
</module>
</page>
import moment from 'moment';
// 模拟业务数据获取
function fetchTableData() {
return Promise.resolve([
{
"name": "邱勇",
"date": "1981-09-24",
"province": "海外",
"city": "双鸭山市",
"zip": "774612",
"address": "双鸭山市容二非片路212号",
"education": "本科",
"occupation": "Java工程师"
},
{
"name": "江敏",
"date": "1981-07-04",
"province": "广东省",
"city": "鞍山市",
"zip": "746656",
"address": "鞍山市身置情路600号",
"education": "本科",
"occupation": "运维"
},
{
"name": "黎静",
"date": "1972-03-30",
"province": "安徽省",
"city": "梧州市",
"zip": "823444",
"address": "梧州市法白员路477号",
"education": "大专",
"occupation": "前端工程师"
},
{
"name": "邱明",
"date": "1979-04-17",
"province": "宁夏回族自治区",
"city": "果洛藏族自治州",
"zip": "881845",
"address": "果洛藏族自治州场也基路922号",
"education": "本科",
"occupation": "Java工程师"
},
{
"name": "孟平",
"date": "1993-07-25",
"province": "四川省",
"city": "中卫市",
"zip": "972238",
"address": "中卫市活之眼路558号",
"education": "本科",
"occupation": "Java工程师"
},
{
"name": "于霞",
"date": "1987-12-23",
"province": "云南省",
"city": "喀什地区",
"zip": "949132",
"address": "喀什地区布万平路313号",
"education": "本科",
"occupation": "DBA"
},
{
"name": "张杰",
"date": "1984-05-15",
"province": "湖北省",
"city": "咸阳市",
"zip": "062896",
"address": "咸阳市段派有志路970号",
"education": "本科",
"occupation": "DBA"
},
{
"name": "林静",
"date": "1989-11-10",
"province": "云南省",
"city": "新竹县",
"zip": "894937",
"address": "新竹县个市布长路317号",
"education": "本科",
"occupation": "运维"
},
{
"name": "汤强",
"date": "1976-03-19",
"province": "香港特别行政区",
"city": "舟山市",
"zip": "153750",
"address": "舟山市接下常毛路496号",
"education": "本科",
"occupation": "DBA"
},
{
"name": "唐秀英",
"date": "2009-07-08",
"province": "湖南省",
"city": "赣州市",
"zip": "328611",
"address": "赣州市完即叫路716号",
"education": "本科",
"occupation": "前端工程师"
},
{
"name": "董秀兰",
"date": "2020-10-04",
"province": "河北省",
"city": "宿州市",
"zip": "787245",
"address": "宿州市方西且路844号",
"education": "大专",
"occupation": "DBA"
},
{
"name": "汤秀兰",
"date": "1999-01-26",
"province": "海南省",
"city": "七台河市",
"zip": "693865",
"address": "七台河市走只场非路467号",
"education": "大专",
"occupation": "DBA"
},
{
"name": "廖勇",
"date": "1977-01-01",
"province": "广西壮族自治区",
"city": "泰州市",
"zip": "653814",
"address": "泰州市容林带太路570号",
"education": "研究生",
"occupation": "DBA"
},
{
"name": "蒋平",
"date": "2020-11-22",
"province": "新疆维吾尔自治区",
"city": "岳阳市",
"zip": "635217",
"address": "岳阳市第最是状路173号",
"education": "研究生",
"occupation": "DBA"
},
{
"name": "林军",
"date": "2004-07-28",
"province": "贵州省",
"city": "防城港市",
"zip": "936227",
"address": "防城港市电后五路52号",
"education": "大专",
"occupation": "DBA"
},
{
"name": "余杰",
"date": "1981-11-13",
"province": "宁夏回族自治区",
"city": "澳门半岛",
"zip": "610244",
"address": "澳门半岛展因由路602号",
"education": "大专",
"occupation": "DBA"
},
{
"name": "薛杰",
"date": "2009-11-19",
"province": "贵州省",
"city": "盘锦市",
"zip": "487452",
"address": "盘锦市义图克路624号",
"education": "本科",
"occupation": "Java工程师"
},
{
"name": "吕平",
"date": "1974-02-17",
"province": "浙江省",
"city": "晋城市",
"zip": "262025",
"address": "晋城市我算情路532号",
"education": "本科",
"occupation": "Java工程师"
},
{
"name": "郭平",
"date": "1973-01-13",
"province": "甘肃省",
"city": "日照市",
"zip": "312303",
"address": "日照市置论史路135号",
"education": "大专",
"occupation": "Java工程师"
},
{
"name": "侯娜",
"date": "2015-03-02",
"province": "重庆",
"city": "绥化市",
"zip": "843136",
"address": "绥化市效思义七路946号",
"education": "大专",
"occupation": "DBA"
}]);
}
export default XPage({
data: {
tableData: [],
educations: [],
},
show() {
this.init();
},
async init() {
const tableData = await fetchTableData();
this.setData({
educations: [
{ label: '全部', value: '' },
{ label: '大专', value: '大专' },
{ label: '本科', value: '本科' },
],
tableData,
});
},
async search(formData) {
const fullTableData = await fetchTableData();
const { name } = formData;
const newTableData = name
? fullTableData.filter(row => row.name.indexOf(name) !== -1)
: fullTableData;
this.setData({
tableData: newTableData,
});
},
handleEditRow(rowData) {
CabinX.alert({
title: '提示',
text: `开始编辑${rowData.name}的数据`,
});
},
handleDeleteRow(rowIndex, rowData) {
const { data } = this.getComponent('table').getData();
CabinX.confirm(
{
title: '提示',
text: '您确定确定删除这条数据吗?',
},
(val) => {
if (val) {
const newTableData = [...data].splice(rowIndex, 1);
this.setData({
tableData: newTableData,
});
}
}
);
},
handleTableSort([{ name, order } = {}]) {
if (!name) {
return;
}
const { data } = this.getComponent('table').getData();
const sortedTableData = [...data];
// 按照出生日期排序
sortedTableData.sort((a, b) => {
const prevBirthDate = moment(a.date);
const nextBirthDate = moment(b.date);
// 升序
if (order === 'asc') {
return prevBirthDate - nextBirthDate;
}
// 其他
return nextBirthDate - prevBirthDate;
});
this.setData({
tableData: sortedTableData,
});
}
});
表格合计
通过设置table的属性summary定义表格列合计。
<page>
<table
data="{{tableData}}"
height="auto"
summary="{{summary}}"
>
<x-cell label="序号" width="60px">
{{cellData.rowNO}}
</x-cell>
<x-cell label="姓名">
{{cellData.rowData.name}}
</x-cell>
<x-cell label="字段1">
{{cellData.rowData.field1}}
</x-cell>
<x-cell label="字段2">
{{cellData.rowData.field2}}
</x-cell>
</table>
</page>
export default XPage({
data: {
sex: [
{ value: '男', label: '男' },
{ value: '女', label: '女' },
],
summary: {
data: [],
},
tableData: [
{
id: '000',
name: '王大虎',
field1: 10,
field2: 20,
},
{
id: '001',
name: '王大虎',
field1: 10,
field2: 20,
},
{
id: '002',
name: '王二虎',
field1: 10,
field2: 20,
},
{
id: '003',
name: '王三虎',
field1: 10,
field2: 20,
},
{
id: '004',
name: '王四虎',
field1: 10,
field2: 20,
},
{
id: '005',
name: '王四虎',
field1: 10,
field2: 20,
},
],
submitData: {},
},
show() {
const { tableData } = this.data;
const { field1, field2 } = tableData.reduce(
(acc, cur) => {
const { field1, field2 } = cur;
acc.field1 += field1;
acc.field2 += field2;
return acc;
},
{ field1: 0, field2: 0 },
);
this.setData({
'summary.data': [
'',
'',
{ label: '合计1', value: field1 },
{ label: '合计2', value: field2 },
],
});
},
handleClick() {},
calcSpan({ rowIndex, columnIndex, row, column }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 3) {
return { rowspan: 1, colspan: 2 };
} else if (columnIndex === 4) {
return { rowspan: 0, colspan: 0 };
}
}
},
});
表格分组小计
在接口返回行数据的基础上,计算出分组小计数据并插入到行数据中,通过span属性设置列合并规则。
<page>
<table
height="auto"
bordered
ajax="{{fetchTableData}}"
span="{{calcSpan}}"
beforeRender="{{beforeRender}}"
beforeRowRender="{{beforeRowRender}}"
bind-rendered="handleTableRendered"
>
<cell label="采销部类">
{{cellData.rowData.aggName}}
</cell>
<cell label="采销部类编码">
{{cellData.rowData.aggCode}}
</cell>
<cell label="库商品" name="sex">
{{cellData.rowData.zeroStockCount}}
</cell>
<cell label="畅缺商品">
{{cellData.rowData.lackStockCount}}
</cell>
<cell label="总店品项数">
{{cellData.rowData.allCount}}
</cell>
<cell label="缺货率">
{{cellData.rowData.stockoutRate}}
</cell>
<cell label="主数据" align="right">
<button text="{{String(cellData.rowData.mainDataExceptionNum)}}" type="link" />
</cell>
<cell label="门店" align="right">
<button text="{{String(cellData.rowData.storeNum)}}" type="link" />
</cell>
<cell label="供应商" align="right">
<button text="{{String(cellData.rowData.purchaseNum)}}" type="link" />
</cell>
</table>
</page>
export default XPage({
data: {},
/**
* 在接口返回数据基础上,计算并新增一条小计行数据
* @param {Object} res
* @returns
*/
beforeRender(res) {
const {
data: { result },
} = res;
let currentGroup;
const rows = [];
result.forEach((item, index) => {
const { groupCode, groupName } = item;
const isLast = index === result.length - 1;
rows.push(item);
if (!currentGroup) {
currentGroup = {
name: groupName,
code: groupCode,
mainDataExceptionNum: 0,
storeNum: 0,
purchaseNum: 0,
};
}
if (currentGroup.code === groupCode) {
currentGroup.mainDataExceptionNum += item.mainDataExceptionNum;
currentGroup.storeNum += item.storeNum;
currentGroup.purchaseNum += item.purchaseNum;
}
if (currentGroup.code !== groupCode || isLast) {
const subtotalRow = {
aggName: `${currentGroup.name}小计`,
isSubtotoal: true,
mainDataExceptionNum: currentGroup.mainDataExceptionNum,
storeNum: currentGroup.storeNum,
purchaseNum: currentGroup.purchaseNum,
};
// 增加小计行数据
if (isLast) {
rows.push(subtotalRow);
} else {
rows.splice(rows.length - 1, 0, subtotalRow);
}
currentGroup = {
name: groupName,
code: groupCode,
mainDataExceptionNum: item.mainDataExceptionNum,
storeNum: item.storeNum,
purchaseNum: item.purchaseNum,
};
}
});
res.data.result = rows;
return res;
},
handleTableRendered() {},
beforeRowRender(rowData) {
if (rowData.isSubtotoal) {
return {
style: { backgroundColor: '#f5f5f5' },
};
}
},
fetchTableData(params) {
return CabinX.ajax({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/children',
method: 'get',
params,
}).then((res) => {
const {
data: { result },
} = res;
const flatData = result.reduce((acc, cur) => {
const {
aggCode: groupCode,
aggName: groupName,
childList,
} = cur;
if (!childList || !childList.length) {
return acc;
}
return acc.concat(
childList.map((item) => {
return {
...item,
groupCode,
groupName,
aggName: `${groupName}${item.aggName}`,
};
}),
);
}, []);
res.data.result = flatData;
return res;
});
},
calcSpan({ rowIndex, columnIndex, row, column }) {
if (!row.isSubtotoal) {
return;
}
const fields = [
'采销部类编码',
'库商品',
'畅缺商品',
'总店品项数',
'缺货率',
];
if (column.label === '采销部类') {
return { rowspan: 1, colspan: fields.length + 1 };
}
if (fields.indexOf(column.label) !== -1) {
return { rowspan: 1, colspan: 0 };
}
},
});
SuperTable 分组小计
summary.group设置分组统计配置
<page title="Table Summary">
<table
x="table"
type="super"
title="合计&分组小计"
editable
summary="{{summary}}"
tips="合计&分组小计demo"
ajax="{{fetchData}}"
before-render="{{beforeTableRender}}"
>
<cell label="采销部类">
{{cellData.rowData.aggName}}
</cell>
<cell label="采销部类编码">
{{cellData.rowData.aggCode}}
</cell>
<cell label="库商品" name="zeroStockCount" formatter="quantity">
{{cellData.rowData.zeroStockCount}}
</cell>
<cell label="畅缺商品" name="lackStockCount">
<editor
node="input"
disabled="{{cellData.rowData.isGroupSummary}}"
value="{{cellData.rowData.lackStockCount}}"
></editor>
</cell>
<cell label="总店品项数" formatter="quantity">
{{cellData.rowData.allCount}}
</cell>
<cell label="缺货率">
{{cellData.rowData.stockoutRate}}
</cell>
<cell label="主数据" align="right">
<button text="{{(cellData.rowData.mainDataExceptionNum || 0).toString()}}" type="link" />
</cell>
<cell label="门店" align="right">
<button text="{{(cellData.rowData.storeNum || 0).toString()}}" type="link" />
</cell>
<cell label="供应商" align="right">
<button text="{{(cellData.rowData.purchaseNum || 0).toString()}}" type="link" />
</cell>
</table>
</page>
export default XPage({
data: {
summary: {
// 分组配置
group: {
key: 'groupCode', // 分组依据该字段
text: '小计',
columns: [
// 分组统计列,通过name关联数据列
{
name: 'zeroStockCount',
},
{
name: 'lackStockCount',
},
],
},
data: [
{ value: 10000, name: 'zeroStockCount', formatter: 'quantity' },
{ label: '合计', value: 20000, name: 'lackStockCount' },
],
},
},
beforeTableRender(res) {
const { totalCount, pageSize, pageCount, currentPage, result } =
res.data;
return {
data: {
records: result,
current: currentPage,
pages: pageCount,
total: totalCount,
size: pageSize,
},
};
},
async fetchData(params) {
return CabinX.ajax({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/children',
method: 'get',
params,
}).then((res) => {
const {
data: { result },
} = res;
const flatData = result.reduce((acc, cur) => {
const {
aggCode: groupCode,
aggName: groupName,
childList,
} = cur;
if (!childList || !childList.length) {
return acc;
}
return acc.concat(
childList.map((item) => ({
...item,
groupCode,
groupName,
aggName: `${groupName}${item.aggName}`,
})),
);
}, []);
res.data.result = flatData;
return res;
});
},
});
SuperTable 跨端
需要设置移动端必须的属性,如:需要指定类型为title的cell
<page title="Super table cross">
<table
x="table"
type="super"
title="跨端的super表格"
ajax="{{fetchData}}"
before-render="{{beforeTableRender}}"
bindrendered="handleTableRendered"
cell-sort="{{['allCount','aggCode']}}"
show-rownum
pullrefresh
bindrefresh="onRefresh"
>
<cell label="商品图片" name="wareImage" width="80px" type="image">
<upload
name="wareImage"
type="image"
max-length="{{1}}"
text="选择图片"
action="{{imageAction}}"
value="{{cellData.rowData.wareImage && [cellData.rowData.wareImage] || []}}"
/>
</cell>
<cell label="采销部类" type="title" name="aggName" copiable="{{valueKey: 'aggCode'}}">
{{cellData.rowData.aggName}}
</cell>
<cell label="状态" type="tag" name="tag">
<tag text="已完成" status="success"></tag>
</cell>
<cell label="采销部类编码" name="aggCode">
{{cellData.rowData.aggCode}}
</cell>
<cell label="库商品" name="zeroStockCount" formatter="quantity">
{{cellData.rowData.zeroStockCount}}
</cell>
<cell label="总店品项数" formatter="quantity" name="allCount">
{{cellData.rowData.allCount}}
</cell>
<cell label="缺货率" name="stockoutRate">
{{cellData.rowData.stockoutRate}}
</cell>
<cell label="主数据" align="right" name="mainDataExceptionNum">
<button text="{{(cellData.rowData.mainDataExceptionNum || 0).toString()}}" type="link"/>
</cell>
<cell label="门店" align="right" name="storeNum">
<button text="{{(cellData.rowData.storeNum || 0).toString()}}" type="link"/>
</cell>
<cell label="供应商" align="right" name="purchaseNum">
<button text="{{(cellData.rowData.purchaseNum || 0).toString()}}" type="link"/>
</cell>
<cell label="操作" type="control" fixed="right" name="control">
<button text="测试1"/>
<button text="测试2"/>
<button text="测试3"/>
<button text="测试4"/>
<button text="测试5"/>
</cell>
</table>
</page>
export default XPage({
data: {
imageAction: '//testgwbasics.dmall-os.com/basics/nessau/io/file/upload', // 按照业务实际上传图片的接口填写
},
beforeTableRender(res) {
const {totalCount, pageSize, pageCount, currentPage, result} =
res.data;
return {
data: {
records: result,
current: currentPage,
pages: pageCount,
total: totalCount,
size: pageSize,
},
};
},
async fetchData(params) {
return CabinX.ajax({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/children',
method: 'get',
params,
}).then((res) => {
const {
data: {result},
} = res;
const flatData = result.reduce((acc, cur) => {
const {
aggCode: groupCode,
aggName: groupName,
childList,
} = cur;
if (!childList || !childList.length) {
return acc;
}
return acc.concat(
childList.map((item) => ({
...item,
groupCode,
groupName,
aggName: `${groupName}${item.aggName}`,
})),
);
}, []);
const [firstRowData] = flatData;
firstRowData.wareImage = {
uid: '1700382728195',
url: 'https://testimage-1256468630.cos.ap-beijing.myqcloud.com/ware/0f1ee4381b584119828261b79e42b024/screenshot-20220507-092953.png',
name: 'screenshot-20220507-092953',
};
res.data.result = flatData;
return res;
});
},
handleTableRendered() {
this.getComponent('table').activateRow(1);
},
onRefresh() {
setTimeout(() => {
this.getComponent('table').stopPullRefresh();
}, 1000);
},
});
SuperTable 筛选
需要设置filterable属性, 配合cell上node属性使用可以参考item组件, 当筛选条件改变后,会触发表格的filter事件。
<page title="SuperTable Filterable">
<table x="table" type="super" ajax="{{fetchData}}" before-render="{{beforeTableRender}}" pageable="{{pageSize: 20}}"
filterable="{{data: {radioButton: '1'}, name: 'keywords', placeholder: '请输入关键字'}}" show-rownum
bindrendered="handleTableRendered" bindfilter="handlerTableFilter">
<cell label="姓名" name="name" sortable node="input">
{{cellData.rowData.name}}
</cell>
<cell label="radioButton" name="radioButton" node="radio" displayType="button"
data="{[{label:'通过', value: '1'},{label:'驳回', value: '0'},{label: '审批中', value: '2'}]}">
{{cellData.rowData.id}}
</cell>
<cell label="checkbox" name="checkbox" node="checkbox"
data="{[{label:'通过', value: '1'},{label:'驳回', value: '0'},{label: '审批中', value: '2'}]}">
{{cellData.rowData.id}}
</cell>
<cell label="select" name="select" node="select"
data="{[{label:'通过', value: '1'},{label:'驳回', value: '0'},{label: '审批中', value: '2'}]}">
{{cellData.rowData.localeName}}
</cell>
<cell label="radio" name="radio" node="radio"
data="{[{label:'通过', value: '1'},{label:'驳回', value: '0'},{label: '审批中', value: '2'}]}">
{{cellData.rowData.id}}
</cell>
<cell label="日期" name="date" sortable node="date-picker">
{{cellData.rowData.date}}
</cell>
<cell label="省/直辖市" name="province">
{{cellData.rowData.province}}
</cell>
<cell label="市区" name="city">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址" name="address">
{{cellData.rowData.address}}
</cell>
<cell label="邮编" name="zip">
{{cellData.rowData.zip}}
</cell>
<cell label="学历" name="education">
{{cellData.rowData.education}}
</cell>
<cell label="职业" name="occupation">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
export default XPage({
data: {},
beforeTableRender(res) {
const { totalCount, pageSize, pageCount, currentPage, result } =
res.data;
return {
data: {
records: result,
current: currentPage,
pages: pageCount,
total: totalCount,
size: pageSize,
},
};
},
async fetchData(params) {
return CabinX.ajax({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
method: 'get',
params,
});
},
handleTableRendered() {
this.getComponent('table').activateRow(1);
},
handlerTableFilter(filterParams) {
console.log('filterParams',filterParams);
this.getComponent('table').query({ params: filterParams });
},
handleEdit() {
},
handleOper() {
},
onRefresh() {
setTimeout(() => {
this.getComponent('table').stopPullRefresh();
}, 1000);
},
});
filterable 配置项
参数 | 说明 | 类型 | 可选值 | 默认值 | 端 | 版本 |
---|---|---|---|---|---|---|
filterable | 是否开启筛选 | Boolean/Object | -- | false | PC/Mobile | -- |
filterable.data | 筛选项数据 | {name,value} | -- | -- | PC/Mobile | -- |
filterable.name | input筛选项key | String | -- | -- | PC/Mobile | -- |
filterable.placeholder | input筛选项placeholder | String | -- | -- | PC/Mobile | -- |
filterable.queryButton | 是否显示筛选按钮 | Boolean | -- | -- | PC/Mobile | -- |
filterable.customAction | 自定义筛选按钮 | Array<{icon: String, click: Function}> | -- | -- | Mobile | -- |
SuperTable 单元格复制
在cell上设置copiable属性,开启单元格复制功能,默认复制name属性对应的值,可以通过valueKey属性指定复制的字段。
<page title="Super table copy demo">
<table
x="table"
type="super"
ajax="{{fetchData}}"
pageable="{{pageSize: 50}}"
before-request="{{beforeRequest}}"
before-render="{{beforeTableRender}}"
bindrendered="handleTableRendered"
>
<cell label="No." fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期">
{{cellData.rowData.date}}
</cell>
<cell label="姓名" name="name" copiable>
{{cellData.rowData.name}}
</cell>
<cell label="省/直辖市">
{{cellData.rowData.province}}
</cell>
<cell label="市区">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址" copiable="{{valueKey: 'address'}}">
{{cellData.rowData.address}}
</cell>
<cell label="邮编">
{{cellData.rowData.zip}}
</cell>
<cell label="学历">
{{cellData.rowData.education}}
</cell>
<cell label="职业">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
export default XPage({
data: {
},
beforeRequest(params) {
const { current, size, ...rest } = params;
return {
currentPage: current,
pageSize: size,
...rest,
};
},
beforeTableRender(res) {
const {totalCount, pageSize, pageCount, currentPage, result} = res.data;
return {
data: {
records: result,
current: currentPage,
pages: pageCount,
total: totalCount,
size: pageSize,
},
};
},
async fetchData(params) {
return CabinX.ajax({ withCredentials: true }).get({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
params,
});
},
handleTableRendered() {
this.getComponent('table').activateRow(1);
},
});
SuperTable 行拖动排序
设置row-draggable属性,开启行拖动排序功能,可以监听row-dragend事件,通过事件参数data属性获取排序后的数据。
<page title="Super table drag sorting">
<table
x="table"
type="super"
pageable="{{pageSize: 10}}"
row-draggable
virtual-scroll="{{false}}"
before-request="{{beforeRequest}}"
before-render="{{beforeTableRender}}"
ajax="{{fetchData}}"
bindrow-dragend="handlerRowDragend"
bindrendered="handleTableRendered"
>
<cell label="No." fixed="left">
{{cellData.rowNO}}
</cell>
<cell label="日期">
{{cellData.rowData.date}}
</cell>
<cell label="姓名" name="name">
{{cellData.rowData.name}}
</cell>
<cell label="省/直辖市">
{{cellData.rowData.province}}
</cell>
<cell label="市区">
{{cellData.rowData.city}}
</cell>
<cell label="详细地址">
{{cellData.rowData.address}}
</cell>
<cell label="邮编">
{{cellData.rowData.zip}}
</cell>
<cell label="学历">
{{cellData.rowData.education}}
</cell>
<cell label="职业">
{{cellData.rowData.occupation}}
</cell>
<cell label="操作" fixed="right">
<button text="编辑" bindclick="handleEdit(cellData.rowData.name)"></button>
<button text="操作" bindclick="handleOper(cellData.rowData.name)"></button>
</cell>
</table>
</page>
export default XPage({
data: {
},
beforeRequest(params) {
const { current, size, ...rest } = params;
return {
currentPage: current,
pageSize: size,
...rest,
};
},
beforeTableRender(res) {
const {totalCount, pageSize, pageCount, currentPage, result} = res.data;
return {
data: {
records: result,
current: currentPage,
pages: pageCount,
total: totalCount,
size: pageSize,
},
};
},
async fetchData(params) {
return CabinX.ajax({ withCredentials: true }).get({
url: '//testapi-nodedmallos.dmall.com/cabinx/pcapi/table/data',
params,
});
},
handlerRowDragend({ oldData, data }) {
console.log('row drag end', oldData, data);
}
});
Attribute
属性 | 说明 | 类型 | 可选值 | 默认值 | 端 | 版本 |
---|---|---|---|---|---|---|
ajax | http请求相关的参数,与data并存时,优先 使用ajax,具体配置参考 ajax配置 | String/Object/(params: Object) => Promise | -- | -- | PC/Mobile | -- |
data | 定义表格显示的数据,与ajax 并存时失效 | Array< Object > | -- | -- | PC/Mobile | -- |
row-key | 行数据的key | String | -- | -- | -- | -- |
type | 类型 | String | normal/super | normal | -- | -- |
editable | 是否开启编辑模式,开启后,可以使 用表格内的编辑组建,开启后组建的使用方式参考 editable | -- | -- | -- | -- | -- |
filterable | 是否开启筛选 | Boolean/Object | -- | false | -- | -- |
pageable | 是否开启 异步 分页,具体配置参考 pageable | Boolean/Object | -- | false | -- | -- |
summary | 表格列合计 | Object{ text: String, data: Array} | -- | -- | -- | -- |
beforeRender | 该回调方法用于将接口数据转换成表格渲染数据 转换成的标准格式参考“beforeRender的返回值格式” | Function | -- | -- | -- | -- |
beforeRequest | 该回调方法用于修改接口的传参格式,默认格式参考“beforeRequest的入参” | Function | -- | -- | -- | -- |
not-cabinx-tag | 如果需要用原生标签,可以 使用这个参数,编译器将不会对 table 转成 x-table 。注意, 这个标签只在命令行编译阶段生效,而不是运行阶段, 所以,赋值对他是没有用的 | -- | -- | -- | PC/Mobile | -- |
column-settable | 是否开启 自定义选择列, 具体配置参考 columnSettable | Boolean/Object | -- | false | -- | -- |
enter | selectable 开启下 回车事件 | Function | -- | false | -- | -- |
maxBtn | 操作栏最大按钮数,超出...,默认3 | Number/String | -- | 3 | -- | -- |
title | 标题 | String | -- | -- | -- | -- |
cell-content-cols | 移动端时cell单行内容区域的列数,最多支持3列排布 | String | 1/2/3 | 1 | -- | -- |
cell-sort | 移动端时每行内容区域的排序,如:["name","id","date"] (为列取值用的key的排序) | Array | -- | -- | -- | -- |
show-more | 仅移动端且type为super时可用,当监听了row-visited事件时需要配置该属性,每行卡片才能展示更多区域。点击该区域可查看改行全部详情信息 | Boolean | -- | false | -- | -- |
pullrefresh | 仅移动端且type为super时可用,下拉刷新,触发下拉刷新时会触发refresh回调函数。注意:需要用户在回调函数中手动执行stopPullRefresh()关闭下拉刷新动效 | Boolean | -- | false | -- | -- |
show-rownum | 是否增加行号列,仅type为super时可用 | Boolean | -- | false | -- | -- |
cellContentLayout | 设置移动端card内容部分部分方式,仅type为super时可用 | String | horizontal/vertical | horizontal | Mobile | -- |
row-draggable | 开启行拖动排序,仅type为super时可用 | Boolean | -- | false | PC | -- |
emptyTextConfig | 表格空数据提示语,可以通过全局配置也可以组件单独配置 | Object | {no_data,no_data_search} | null | PC | -- |
beforeRender的返回值格式
第一种
{
code:'',//错误码(非必须)
data:{
result:[{},{}],//列表数据
currentPage:1,//当前的页码
pageCount:10,//总页数
totalCount:100,//总数据条数
pageSize:10//每页条数
}
}
第二种
{
data:[{},{},{}],//列表数据
pagination:{
total:100,//总数据条数
per_page:10,//每页条数
current_page:1,//当前的页码
last_page:10//总页数
}
}
beforeRequest的入参
// 参数1 Object({ currentPage: Number, pageSize: Number })
{
currentPage: 1
pageSize: 50
... //用户参数平铺
}
// 参数2 Array<{name: String, order: 'asc' | 'desc' }>
[
{ order: 'asc', name: 'personName'}
]
ajax配置
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
ajax | 如果ajax为string时,表示请求的url 作用与 ajax:{url:'xxx.dmall.com/abc/abc.json'} 相同 | String | ||
ajax.url | 请求的url | String | ||
ajax.params | 请求的参数 | Object | ||
ajax.method | http method | string | get/post | |
ajax.contentType | 请求资源MIME类型 注意:由于公司禁止使用options请求, 所以可以选值请参考多点研发必知必会中的 跨域问题 章节 跨域请求时,Content-Type默认为application/json, browser会发起预检请求(method: options), 由于安全原因公司部分接口禁止options请求, 所以预检通过不过会报403,开发过程中发现这种情况, 请检查Content-Type是否为允许的三种类型 | String | application/json application/x-www-form-urlencoded multipart/form-data text/plain | application/json |
pageable 分页器
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
pageable | 是否开启异步分页,!!默认不会开启!!,关闭情况下,只会从服务器拉取50条数据 | boolean/object | true/false/Object | false |
pageable.pageSize | 默认每页条数 | Number | 50 | |
pageable.mode (pc端可用) | 展示模式 | String | complex/simple | complex |
pageable.showSimpleCount (pc端可用) | 当为 mode 为 simple 时生效,显示当前页/总页数式 | Boolean | false | |
pageable.pageSizes | 每页条数选项设置 | Number[] | [10, 20, 50, 100] | |
请求方式 | String | GET/POST | GET | |
pageable.httpOptions | 请求关信息 | Object | ||
pageable.httpOptions.withCredentials | 是否携带cookie | Boolean | true/false | true |
pageable.httpOptions.headers | 请求头相关信息 | Object | ||
pageable.showPageSize(pad端可用) | 显示每页可选展示条数下拉列表 | Object | ||
设置请求的content-type, 注意:由于公司禁止使用option请求,所以可以选值请参考多点研发必知必会中的 跨域问题 章节 | String |
editable 编辑模式
名称 | 说明 | 可选值 | 默认值 |
---|---|---|---|
shortcutType | 快捷键模式 | common/contract(更加方便的快捷键功能) | common |
columnSettable 列设置
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
columnSettable | 是否开启 自定义选择列,默认不会开启!!关闭情况下,不展示表格右上角的按钮 | boolean/object | true/false/Object | false |
columnSettable.tips | 点击按钮之后右侧弹出列的标题 | String | '' | |
columnSettable.draggable | 是否可以拖动 | Object | true/false | true |
columnSettable.persist | 是否持久化 | Boolean | true/false | false |
columnSettable.initialColumns | 初始列 | Array<{ name: String, visible: Boolean, fixed: 'left|content|right' }> |
selectable 行选择器
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
selectable | 是否开启行选择器 | Boolean/Object | false | |
selectable.multiple | 是否为复选 | Boolean | true/false | false |
selectable.showCheck | 是否展示勾选图标,仅在multiple为false生效 | true/false | true | |
selectable.multipage | 是开启跨页选择 | Boolean | true/false | false |
selectable.valueKey | 设置某个行数据属性,初始选中项值,跨页必填 | String | ||
selectable.labelKey | 设置某个行数据属性,初始选中项文本,跨页必填 | String | ||
selectable.initialMultipageSelected | 跨页选中初始值 | Array<{label: String, value: any}> | [] | |
selectable.rowSelectable | multiple 为真时如果开启,允许点击行选中 | Boolean | false | |
selectable.beforeRenderCheckbox | 控制多选中的checkbox是否可见(仅super table) | Function | - |
Event
名称 | 说明 | 参数 |
---|---|---|
rendered | 渲染完成回调 | |
selected | selectable 的选择器选中后触发 | { data: Array< CellData >, row: Array< ChangedRowIndex >, selected: Array< SelectedIndex > } |
unselected | selectable 的选择器反选后触发 | { data: Array< CellData >, row: Array< ChangedRowIndex >, selected: Array< SelectedIndex > } |
selected-all | 手动勾选全选 Checkbox 时触发的事件,type="super"生效 | { data: Array< CellData >, row: Array< ChangedRowIndex >, selected: Array< SelectedIndex > } |
unselected-all | 手动取消全选 Checkbox 时触发的事件,type="super"生效 | { data: Array< CellData >, row: Array< ChangedRowIndex >, selected: Array< SelectedIndex > } |
sort | 排序条件发生变化时触发该事件 | Array<{name: String, order: 'asc|desc'}> |
column-changed | 列设置改变后触发 | Array<{name: String, visible: Boolean, fixed: 'left|content|right' }> |
editor-focus | 当editor变为选中态时触发 | {colIndex, rowIndex} |
refresh | 开启pullrefresh下拉刷新时,触发下拉时触发,需要在该回调中调用stopPullRefresh关闭下拉刷新动效 | -- |
row-visited | 行被访问时(双击行)触发,仅type="super"生效 | { visited: String | Number, rowData: Object } |
row-activated | 行聚焦时触发,仅type="super"生效 | { activated: String | Number, rowData: Object } |
row-focused | 行hover时触发,仅type="super"生效 | { focused: String | Number, rowData: Object } |
row-dragend | 行拖动结束后触发,仅type="super"生效, 事件参数回返回排序后的数据 | { data: Object, oldData: Object } |
filter | 筛选条件改变时触发,仅type="super"生效 | Object |
multipage-select-cleared | 点击清除跨页选择框中的已选中项后触发该事件 | { data: Array, value: Any, selected: Array } |
multipage-select-cleared-all | 点击跨页选择框中的清空按钮后触发该事件 | { data: Array, selected: Array } |
methods 方法
query
更改分页器的请求参数,并且重新发起请求, 可以一次传递多个。
- 入参
1.undefined
保留当前 业务参数 页码 每页条数 请求方式 option ,达到刷新的效果,可用于页面返回后刷新数据
2.{}
清空业务参数(注意:并不是重置为初始值) 页码设置为1 保留每页条数 请求方式 option
3.<strong style="color:#ff0000">Tips:分页信息请勿在params中设置,比如:pageSize、currentPage等字段。如需设置请参考如下配置。</strong>
{
url:''// 请求url,如未设置使用上次的
params: {} ,// 业务请求参数,如未设置使用上次的
pageSize: 10 // 每页的数据条数,如未设置使用上次的
pageNum: 1 // 跳转的页码,如为传递则设置为1
httpMethod // 如未设置使用上次的
httpOptions// 如未设置使用上次的
}
示例
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1">
...
</table>
js:
this.getComponent('table1').query({
url:http://testapi.dmall.com/testapi1
});
- 出参:无
selectAll
selectable 开启后,选择所有checkbox
- 入参:无
- 出参:无
- 使用:
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1" :selectable={multiple:true}>
...
</table>
js:
this.getComponent('table1').selectAll()
unselectAll
selectable 开启后,取消所有checkbox
- 入参:无
- 入参:({ multipage: Boolean }) options 当输入对象中 multipage 为 ture 时,表示跨页清空所有checkbox
- 出参:无
- 使用:
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1" :selectable={multiple:true}>
...
</table>
<table x='table2' selectable="{{ multiple: true, multipage: true, valueKey: 'name', labelKey: 'name'}}">
...
</table>
js:
this.getComponent('table1').unselectAll();
this.getComponent('table2').unselectAll({multipage: true});
unselect
selectable 开启后,取消选中
- 入参:(rowNum: Array | Number) rowNum 行号
- 出参:无
- 使用:
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1" :selectable={multiple:true}>
...
</table>
js:
this.getComponent('table1').unselect(0)
this.getComponent('table1').unselect([0,1,2,3])
select
selectable 开启后,选中
- 入参:(rowNum: Array | Number) rowNum 行号
- 出参:无
- 使用:
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1" :selectable={multiple:true}>
...
</table>
js:
this.getComponent('table1').select(0)
this.getComponent('table1').select([0,1,2,3])
this.getComponent('table1').select([{rowNum:0, attrs:{disabled:true}},{rowNum:1, attrs:{disabled:true}}])
getData
获取表格的数据
- 入参:无
- 出参:
{
data : [], // 表格原始数据(为编辑)
selected : [],// selectable 开启后,得到选中行索引(从0开始),比如[0, 2]
edited:[], //editable 开启后,得到编辑过的数据
}
- 使用:
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1" :selectable={multiple:true} editable>
...
</table>
js:
let tableData = this.getComponent('table1').getData();
console.log(tableData.data)
console.log(tableData.selected)
console.log(tableData.edited)
expandRow
展开行
- 入参:(rowKey: String, callback: Function) 表格rowKey属性, callback 回调函数
- 出参: 无
- 使用:
dml:
<table x='table' row-key="aggCode">
</table>
js:
this.getComponent('table').expandRow('AH01', () => {
});
getMultipageSelected
获取跨页选中项
- 入参:无
- 出参:Array<{label: String, value: Any}>
- 使用:
dml:
<table x='table1' selectable="{{ multiple: true, multipage: true, valueKey: 'name', labelKey: 'name'}}">
...
</table>
js:
const selected = this.getComponent('table1').getMultipageSelected();
console.log(selected)
focusEditor
选中并激活某个单元格
- 入参:(rowIndex: Number, colIndex: Number | String) rowIndex 表格行的index, colIndex表格列的index,也可传入列的name
- 出参:无
- 使用:
dml:
<table x='table1' editable>
...
</table>
js:
const table = this.getComponent('table1');
table.focusEditor(1,1);
activateRow
激活行,仅type="super"时可用
- 入参:(rowNum: Number) rowNum 行号
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
this.getComponent('table1').activateRow(1);
focusRow
focus行,仅type="super"时可用
- 入参:(rowNum: Number) rowNum 行号
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
this.getComponent('table1').focusRow(1);
stopPullRefresh
关闭下拉刷新的动效,仅移动端,type='super'和开启了pullrefresh时可用
- 入参:无
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
onRefresh(){
setTimeout(() => {
this.getComponent('table1').stopPullRefresh();
}, 1000);
}
moveRows
上、下移动表格行
- 入参:(selectedRows: Array | Number, offset: Number) selectedRows 选中的行号, offset 移动的偏移量
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
handleMove(offset) {
const table = this.getComponent('table');
const selected = table.getData().selected || [];
const hasSelected = !!selected.length;
if (hasSelected) {
table.moveRows(selected, offset);
}
},
scrollTo
表格滚动指定位置
- 入参:(x: Number, y: Number) x 水平滚动距离, y 垂直滚动距离.
- 入参:({rowIndex: Number}) rowIndex 指定的滚动的行
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
scrollTo(){
this.getComponent('table1').scrollTo(null, 120);
},
scrollToRowIndex() {
const rowIndex = 5;
this.getComponent('table1').scrollTo({ rowIndex });
},
expandRow
表格树形节点展开
- 入参:(rowKey: String, callback: Function) rowKey 使用前要先配置表格属性row-key值对应的cell上的name并注意唯一性, callback 全部展开后回调函数.
- 出参:无
- 使用:
dml:
<table x='table1' row-key="cellName">
...
</table>
js:
expandAllRow() {
this.getComponent('table1').expandRow(rowKey, (children)=>{
console.log(children)
});
},
collapseRow
表格树形节点收起
- 入参:(rowKey: String) rowKey 使用前要先配置表格属性row-key值对应的cell上的name并注意唯一性
- 出参:无
- 使用:
dml:
<table x='table1' row-key="cellName">
...
</table>
js:
expandAllRow() {
this.getComponent('table1').collapseRow(rowKey);
},
expandAllRow
表格树形全部节点展开
- 入参:(callback: Function) 全部展开后回调函数.
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
expandAllRow() {
this.getComponent('table1').expandAllRow((expendRowKeys)=>{
console.log(expendRowKeys)
});
},
collapseAllRow
表格树形全部节点收起
- 入参:(callback: Function) 全部收起后回调函数.
- 出参:无
- 使用:
dml:
<table x='table1'>
...
</table>
js:
expandAllRow() {
this.getComponent('table1').collapseAllRow((collapseRowKeys)=>{
console.log(collapseRowKeys)
});
},
Slot
cell
列渲染逻辑,可配置属性:
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
name | 调用getData()后这个字段在editd中的字段名(具体参考“编辑table”), 如不指定则会使用列号来标识 | String | ||
label | 列的标题 | String | ||
sortable | 开启排序, 需要同时设置name | Boolean | false | |
ellipsis | 开启超宽自动省略, 需要同时设置width | Boolean | false | |
span | 跨行设置,内置'same', 自定义函数返回{ rowspan: Number, colspan: Number } | String|Function | 'same'\function(){} | |
align | 对齐方式 | String | left/center/right | left |
visible | 是否展示该列 | Boolean | true/false | true |
tips | 提示 | String | ||
type | 列类型,跨端该列会放在对应指定的位置 | String | image/title/tag/control | |
copiable | 开启单元格复制功能 | Boolean|{valueKey: String} | false |
cell type可选值
跨到移动端时,每行数据以卡片的形式展示,每个卡片分别由:主图区、标题区、标签区、内容区、快捷编辑区、操作区几个模块组成。其中有些区域需要用户明确指定,可通过cell的type属性配置,释义如下表:
参数 | 说明 | 必须 |
---|---|---|
image | 主图,标明该列内容放在主图区,仅支持一列 | |
title | 标题,标明该列内容放在标题区,仅支持一列 | 移动端必须配置 |
tag | 标签,标明该列内容放在标签区,仅支持一列 | |
control | 操作,标明该列内容放在操作区,仅支持一列 |
快捷编辑区:当cell内容为editor组件的前三个会放在快捷编辑区域。 内容区:除去上面其他区域的列会放在内容区域,内容区域支持1,2,3列三种排列布局,但无论哪种布局方式,内容最多不超过5行。
移动端每行的卡片默认点击可展示当前行的全部详细内容。如果table上监听了row-visited事件,点击卡片只会触发用户自定义事件,此时查看详情则需要手动配置show-more属性,点击更多区域打开详情。
cell内可用数据
{
"colIndex": 0, //列号
"rowIndex": 0, //行号
"colData": { "label": "No.", "fixed": "left" },//列头信息
//行数据
"rowData": { "date": "2016-05-03", "name": "王大虎", "province": "上海", "city": "普陀区", "address": "上海市普陀区金沙江路 1518 弄", "zip": "200333", "education": "本科", "occupation": "前端工程师" } }
empty
没有数据时候的展示
- 示例:
dml:
<table x='table1' ajax="http://testapi.dmall.com/testapi1" :selectable={multiple:true} editable>
...
<empty>
没有数据...
<empty>
</table>
表格搜索
注意设置 initEmptyRow:false,否则搜索会有问题
<table x='table1' :searchBoxFilter='searchBoxFilter'>
</table>
export default Xpage({
showSearchBox() {
// 展示或者关闭搜索框
this.getComponent('table1').toggleSearchBox();
},
searchBoxFilter({ data, rowIndex, colIndex,colName, filterValue }) {
//自定义规则,根据 colName 等规则判断
//巨量表格可能会有性能问题
console.log(data)
if (colIndex === 1) {
return true;
}
return false;
},
});
属性 | 说明 | 类型 | 可选值 | 默认值 | 端 | 版本 |
---|---|---|---|---|---|---|
searchBoxFilter | 表格搜索回调方法 | Function({data,rowIndex,colIndex,colName,filterValue}) | -- | -- | PC | -- |
调用表格的 toggleSearchBox
方法 开启或者关闭搜索框;