GridManager 庫地址:http://gridmanager.lovejavascript.com/index.html
本文旨在説明 GridManager 的使用技巧,如果想了解其配置使用,詳見文檔説明 https://gridmanager.lovejavascript.com/api/index.html
1. 基礎使用—動態數據表格
export default class App extends Component {
resource = () =>
fetch(
"https://www.lovejavascript.com/learnLinkManager/getLearnLinkList"
).then((res) => res.json());
columnData = [
{
key: "name",
text: "名稱",
align: "left"
},
{
key: "info",
text: "使用説明"
}
];
render() {
return (
<div className="App">
<Table
gridManagerName="test"
disableLine
supportAjaxPage
checkboxConfig={{ useRowCheck: true }}
supportDrag={false}
supportCheckbox={false}
ajaxData={this.resource}
columnData={this.columnData}
/>
</div>
);
}
完整代碼演示:https://codesandbox.io/s/optimistic-currying-1bxpj?file=/src/App.js
2. 靜態數據表格(分頁、排序、搜索、下載)
使用場景:需要純前端處理表格數據,這時候,我們往往需要在前端實現分頁、排序、搜索和下載等函數的封裝。
因為每次刷新表格的時候,都會調用 ajaxData 方法,這個方法會返回表格數據,因此,我們只需要在 ajaxData 方法中調用上述封裝好的函數即可達到我們要的效果。
這種寫法很像過濾器,每一個方法都是對原數據的一次過濾,最後返回過濾後的數據,下面是每個方法的實現:
原始數據originData
—filter—> searchData(originData): searchedData
—filter—> sortingData(searchedData): sortedData
—filter—> paging(sortedData): pagedData
——>處理後的數據
ajaxData 配置:
ajaxData = async (settting, params) => {
const originData = this.store.fetchData();
const searchedData = this.store.searchData(originData, this.state.keywords);
const sortedData = this.store.sortingData(searchedData, params);
this.csvData = sortedData.list;
return await this.store.pagingData(
sortedData,
params.pageNum,
params.pageSize
);
};
分頁:
pagingData(data, pageNum, pageSize) {
const { list } = data;
return Promise.resolve({
pageNum,
pageSize,
totals: list.length,
list: list.slice((pageNum - 1) * pageSize, pageNum * pageSize)
});
}
排序:
sortingData(data, query) {
let sortProps = "DESC";
let sortOrder = "";
Object.keys(query).forEach((key) => {
if (query[key] === "ASC" || query[key] === "DESC") {
sortProps = key.split("_")[1];
sortOrder = query[key];
}
});
const list = this.sort(data.list, sortProps, sortOrder);
return {
totals: list.length,
list
};
}
sort(list, sortProps, sortOrder) {
if (sortOrder === "ASC") {
return sortBy(list, sortProps);
}
if (sortOrder === "DESC") {
return sortBy(list, sortProps).reverse();
}
return list;
}
搜索關鍵字:
searchData(data, keywords) {
const list = data.list.filter(
(item) => item.name && item.name.indexOf(keywords) > -1
);
return {
totals: list.length,
list
};
}
下載:
download(list, fileName) {
if (!fileName) return;
const url = window.URL.createObjectURL(
new window.Blob([`\ufeff${list.join("\r\n")}`])
);
const link = document.createElement("a");
const evt = document.createEvent("MouseEvents");
link.href = url;
link.setAttribute("download", fileName);
evt.initEvent("click");
link.dispatchEvent(evt);
}
完整代碼演示: https://codesandbox.io/s/beautiful-faraday-jt3i3?file=/src/App.js
3. 多選表格(數據回顯、設置行選中的唯一key值、禁用行選中、最大選中行的限制)
表格選中數據回顯
getCheckedData() {
return Table.getCheckedData(this.gridManagerName);
}
setCheckedData(checkedData) {
Table.setCheckedData(this.gridManagerName, checkedData);
}
ajaxSuccess() {
this.setCheckedData(this.state.selected);
}
設置行選中的唯一key值:
表格方法 getCheckedData 返回的是完整的已選數據,表格回顯的前提是傳入的數據和傳出的數據格式一樣,這在使用中會造成侷限,比如説後端並不會存儲完整的數據,而是隻存儲每條數據的 id,這是很常見的場景,因此在 GridManager 後面的迭代中,在 checkboxConfig 中添加了 key 屬性,只需要配置 key: 'id',在傳入的已選數據中,每條數據只需要包括 id 即可,不需要完整的數據結構也可以完成回顯。
<Table
checkboxConfig: { useRowCheck: true, key: 'id' },
/>
禁用行選中
onGridRowRender(row) {
const disabledId = [69, 68];
if (disabledId.indexOf(row.id) > -1) {
Object.assign(row, { gm_checkbox_disabled: true });
}
return row;
}
最大選中行限制:
需要調用 checkedGridBefore 和 checkedGridAllBefore 這兩個方法來完成此需求,由於觸發 checkedAllBefore 之後也會觸發 checkedBefore,因此這裏需要特殊處理一下,防止出現兩次 error 提示,詳細見下面的代碼實現。
checkedGridBefore = (checkedList, isChecked) => {
if (checkedList.length >= MAX_NUM && !isChecked) {
Message.error("最多支持同時選擇5個");
return false;
}
return true;
};
checkedGridAllBefore(checkedList, isChecked) {
const unChecked = this.dataList
.map((item) => !checkedList.find((item1) => item.id === item1.id))
.filter(Boolean);
if (unChecked.length + checkedList.length > MAX_NUM && !isChecked) {
// 觸發 checkedAllBefore 之後也會觸發 checkedBefore,這裏需要特殊處理一下,防止出現兩次 error 提示
if (checkedList.length < MAX_NUM) {
Message.error("最多支持同時選擇5個");
}
return false;
}
return true;
}
完整代碼演示:https://codesandbox.io/s/dazzling-albattani-o7dtn?file=/src/App.js
4. 樹狀表格
在表格基本配置的基礎上,添加 supportTreeData = true 以及 treeConfig 即可完成一個樹表格的展示。
...
supportTreeData
treeConfig={{ treeKey: "children" }}
...
完整代碼演示:https://codesandbox.io/s/shy-smoke-7ltz2?file=/src/App.js
5. 常用的一些使用優化(firstLoading, isIconFollowText,拖拽、隱藏列)
firstLoading:
設置 firstLoading = false,可以讓表格先渲染出來,然後再加載數據。
使用場景:表格數據的請求返回較慢,這時,設置 firstLoading = false,表格就會先渲染,交互上會更加友好。
注意事項:需要配合 callback 函數使用,在 callback 函數中調用刷新表格的方法。
reloadGrid(gotoPage) {
Table.setQuery(this.gridManagerName, this.queryParams, gotoPage);
}
gridInit = () => {
this.reloadGrid(1);
};
render() {
return (
<div className="App">
<Table
gridManagerName={this.gridManagerName}
disableLine
supportAjaxPage
ajaxData={this.ajaxData}
columnData={this.columnData}
supportCheckbox={false}
firstLoading={false}
callback={this.gridInit}
/>
</div>
);
}
完整代碼演示:https://codesandbox.io/s/quirky-https-k06m9?file=/src/App.js
isIconFollowText:
可以設置表頭的icon圖標是否跟隨文本,默認圖標是在左側,設置後會跟在文本右側
columnData = [
{
key: "name",
text: "名稱",
align: "left",
sorting: "",
// 表頭 tooltip 配置
remind: {
text: "字段説明字段説明字段説明字段説明字段説明字段説明",
style: {
"text-align": "left"
}
}
}
];
render() {
return (
<div className="App">
<Table
gridManagerName={this.gridManagerName}
disableLine
supportAjaxPage
ajaxData={this.ajaxData}
columnData={this.columnData}
supportCheckbox={false}
isIconFollowText
/>
</div>
);
}
完整代碼演示:https://codesandbox.io/s/interesting-dust-wwe85?file=/src/App.js:574-1194
拖拽:
在拖拽的場景中,如果涉及到表格的新增和刪除,不要直接對 ajaxData 進行操作,操作原數據,ajaxData 由原數據包裝而來,從而保證單一職責(詳細栗子請看完整代碼)。
ajaxData = async (settting, params) => {
return Promise.resolve({
data: this.state.dataList, // dataList:原數據
totals: this.state.dataList.length
});
};
onAdd() {
const { dataList } = this.state; // dataList:原數據
dataList.push({
id: new Date().getTime(),
name: "瀏覽器的工作原理"
});
this.setState({ dataList });
this.reloadGrid();
}
render() {
const moveRowConfig = {
key: "priority",
handler: (list, tableData) => {
console.log(tableData);
},
useSingleMode: true // 第一列顯示拖拽圖標
};
return (
<div className="App">
<Button onClick={() => this.onAdd()}>新增</Button>
<Table
gridManagerName={this.gridManagerName}
disableLine
supportAjaxPage={false}
ajaxData={this.ajaxData}
columnData={this.columnData}
supportCheckbox={false}
supportMoveRow
moveRowConfig={moveRowConfig}
/>
</div>
);
}
完整代碼演示:https://codesandbox.io/s/jovial-water-8y4if?file=/src/App.js
隱藏列
使用場景:需要展示的列比較多或者有隱藏列的需求。
使用:在 columnData 數組新增一項配置即可
{
key: "operate",
disableCustomize: true,
text: (
<Icon
type="config"
style={{ cursor: "pointer", fontWeight: "bold" }}
onClick={() => this.onSetUpGridFiled()}
/>
),
template: () => "",
width: "30px"
}
onSetUpGridFiled() {
Table.setConfigVisible(this.gridManagerName, true);
}
完整代碼演示:https://codesandbox.io/s/sharp-perlman-1elht?file=/src/App.js:1094-1174