mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-07 13:48:31 +08:00
feat(table): refractor table unfinished,fixed bug,remove only custom trigger onchange,change onchange params,add demo with ajax,fixed header,filter and sorter
This commit is contained in:
parent
28ddaa8d48
commit
f9c7ae76bf
135
demo/documentation/components/table/enUS/ajaxUsage.md
Normal file
135
demo/documentation/components/table/enUS/ajaxUsage.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# Ajax
|
||||||
|
|
||||||
|
```html
|
||||||
|
<n-button @click="sortName" style="margin-right:5px;">sort name</n-button>
|
||||||
|
<n-button @click="clearFilters" style="margin-right:5px;"
|
||||||
|
>clear filters</n-button
|
||||||
|
>
|
||||||
|
<n-button @click="clearFiltersAndSorters">clear filters and sorters</n-button>
|
||||||
|
|
||||||
|
<n-advanced-table
|
||||||
|
style="margin-top:10px;"
|
||||||
|
ref="table"
|
||||||
|
:columns="columns"
|
||||||
|
:data="data"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination"
|
||||||
|
@on-change="onChange"
|
||||||
|
>
|
||||||
|
</n-advanced-table>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
const _columns = $this => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: "Name",
|
||||||
|
key: "name",
|
||||||
|
sortable: true,
|
||||||
|
sorter: "custom",
|
||||||
|
render(h, params) {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{params.row.name.first} {params.row.name.last}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Gender",
|
||||||
|
key: "gender",
|
||||||
|
filterable: true,
|
||||||
|
filterItems: [
|
||||||
|
{ label: "Male", value: "male" },
|
||||||
|
{ label: "Female", value: "female" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Email",
|
||||||
|
key: "email"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
columns: _columns(this),
|
||||||
|
loading: false,
|
||||||
|
total: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getData().then(data => {
|
||||||
|
this.data = data.results;
|
||||||
|
this.total = 100;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pagination() {
|
||||||
|
return { total: this.total, limit: 5, custom: true };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getData(params = {}) {
|
||||||
|
this.loading = true;
|
||||||
|
if (!params.results) {
|
||||||
|
params.results = this.pagination.limit;
|
||||||
|
}
|
||||||
|
if (!params.page) {
|
||||||
|
params.page = this.pagination.currentPage;
|
||||||
|
}
|
||||||
|
let url = "https://randomuser.me/api";
|
||||||
|
let paramsArr = [];
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
if (Array.isArray(params[key])) {
|
||||||
|
params[key].forEach(value => {
|
||||||
|
paramsArr.push(`${key}[]=${value}`);
|
||||||
|
});
|
||||||
|
} else paramsArr.push(`${key}=${params[key]}`);
|
||||||
|
});
|
||||||
|
if (paramsArr.length) {
|
||||||
|
url = url + "?" + paramsArr.join("&");
|
||||||
|
}
|
||||||
|
console.log("TCL: fetch -> url", url);
|
||||||
|
|
||||||
|
return fetch(url)
|
||||||
|
.then(res => res.json())
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChange({ filter, sorter, pagination }) {
|
||||||
|
let params = {
|
||||||
|
page: pagination.currentPage
|
||||||
|
};
|
||||||
|
if (sorter) {
|
||||||
|
Object.assign(params, {
|
||||||
|
sortField: sorter.field,
|
||||||
|
sortOrder: sorter.order
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (filter) {
|
||||||
|
Object.assign(params, {
|
||||||
|
...filter
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.getData(params).then(data => {
|
||||||
|
this.data = data.results;
|
||||||
|
});
|
||||||
|
console.log(filter, sorter, pagination);
|
||||||
|
},
|
||||||
|
sortName() {
|
||||||
|
this.$refs.table.sort("name", "ascend");
|
||||||
|
},
|
||||||
|
clearFilters() {
|
||||||
|
this.$refs.table.filter(null);
|
||||||
|
},
|
||||||
|
clearFiltersAndSorters() {
|
||||||
|
this.$refs.table.filter(null);
|
||||||
|
this.$refs.table.sort(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
@ -1,12 +1,19 @@
|
|||||||
# Filter and sorter
|
# Filter and sorter
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
<n-button @click="sortName" style="margin-right:5px;">sort name</n-button>
|
||||||
|
<n-button @click="clearFilters" style="margin-right:5px;"
|
||||||
|
>clear filters</n-button
|
||||||
|
>
|
||||||
|
<n-button @click="clearFiltersAndSorters">clear filters and sorters</n-button>
|
||||||
|
|
||||||
<n-advanced-table
|
<n-advanced-table
|
||||||
|
style="margin-top:10px;"
|
||||||
ref="table"
|
ref="table"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="data"
|
:data="data"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
@on-selected-change="onSelectedChange"
|
@on-change="onChange"
|
||||||
>
|
>
|
||||||
</n-advanced-table>
|
</n-advanced-table>
|
||||||
```
|
```
|
||||||
@ -16,11 +23,16 @@ const _columns = $this => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: "Name",
|
title: "Name",
|
||||||
key: "name"
|
key: "name",
|
||||||
|
sortable: true,
|
||||||
|
sorter(rowA, rowB) {
|
||||||
|
return rowA.name.length - rowB.name.length;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Age",
|
title: "Age",
|
||||||
key: "age",
|
key: "age",
|
||||||
|
defaultSortOrder: "ascend",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
sorter(rowA, rowB) {
|
sorter(rowA, rowB) {
|
||||||
return rowA.age - rowB.age;
|
return rowA.age - rowB.age;
|
||||||
@ -86,6 +98,20 @@ export default {
|
|||||||
return { total: this.data.length, limit: 5 };
|
return { total: this.data.length, limit: 5 };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {}
|
methods: {
|
||||||
|
onChange({ filter, sorter, pagination }) {
|
||||||
|
console.log(filter, sorter, pagination);
|
||||||
|
},
|
||||||
|
sortName() {
|
||||||
|
this.$refs.table.sort("name", "ascend");
|
||||||
|
},
|
||||||
|
clearFilters() {
|
||||||
|
this.$refs.table.filter(null);
|
||||||
|
},
|
||||||
|
clearFiltersAndSorters() {
|
||||||
|
this.$refs.table.filter(null);
|
||||||
|
this.$refs.table.sort(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
66
demo/documentation/components/table/enUS/fixedHeader.md
Normal file
66
demo/documentation/components/table/enUS/fixedHeader.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Fixed Header
|
||||||
|
|
||||||
|
Display large amounts of data in scrollable view.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<n-advanced-table
|
||||||
|
ref="table"
|
||||||
|
:columns="columns"
|
||||||
|
:data="data"
|
||||||
|
:pagination="pagination"
|
||||||
|
max-height="250px"
|
||||||
|
@on-selected-change="onSelectedChange"
|
||||||
|
>
|
||||||
|
</n-advanced-table>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
const _columns = $this => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: "Name",
|
||||||
|
key: "name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Age",
|
||||||
|
key: "age"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Address",
|
||||||
|
key: "address"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = [];
|
||||||
|
for (let i = 0; i < 46; i++) {
|
||||||
|
data.push({
|
||||||
|
key: i,
|
||||||
|
name: `Edward King ${i}`,
|
||||||
|
age: 32,
|
||||||
|
address: `London, Park Lane no. ${i}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: data,
|
||||||
|
columns: _columns(this),
|
||||||
|
selectedData: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pagination() {
|
||||||
|
return { total: this.data.length, limit: 10 };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
sendMail(rowData) {
|
||||||
|
this.$NMessage.info("send mail to " + rowData.name);
|
||||||
|
},
|
||||||
|
onSelectedChange(selectedData) {
|
||||||
|
this.selectedData = selectedData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
@ -13,6 +13,8 @@ Table is used to displays rows of data.
|
|||||||
basic
|
basic
|
||||||
select
|
select
|
||||||
filterAndSorter
|
filterAndSorter
|
||||||
|
ajaxUsage
|
||||||
|
fixedHeader
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div
|
<div
|
||||||
v-if="pagination !== false && showingData.length"
|
v-if="pagination !== false"
|
||||||
:style="tableWrapperStl"
|
:style="tableWrapperStl"
|
||||||
class="n-advance-table__pagination"
|
class="n-advance-table__pagination"
|
||||||
>
|
>
|
||||||
@ -147,6 +147,17 @@ import themeable from '../../../mixins/themeable'
|
|||||||
import { Store, storageMixin } from '../store'
|
import { Store, storageMixin } from '../store'
|
||||||
import BaseTable from '../baseTable/baseTable'
|
import BaseTable from '../baseTable/baseTable'
|
||||||
|
|
||||||
|
const sortOrderMap = {
|
||||||
|
ascend: -1,
|
||||||
|
descend: 1,
|
||||||
|
unset: 0
|
||||||
|
}
|
||||||
|
const sortOrderReverseMap = {
|
||||||
|
'-1': 'descend',
|
||||||
|
'1': 'ascend',
|
||||||
|
'0': 'unset'
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store () {
|
store () {
|
||||||
return new Store()
|
return new Store()
|
||||||
@ -334,9 +345,9 @@ export default {
|
|||||||
if (this.pagination) {
|
if (this.pagination) {
|
||||||
// TODO: check count limit is exisit
|
// TODO: check count limit is exisit
|
||||||
let total = this.pagination.total
|
let total = this.pagination.total
|
||||||
if (this.pagination.custom !== true) {
|
// if (this.pagination.custom !== true) {
|
||||||
total = this.data.length
|
// total = this.data.length
|
||||||
}
|
// }
|
||||||
return Math.ceil(total / this.pagination.limit) || 1
|
return Math.ceil(total / this.pagination.limit) || 1
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
@ -348,7 +359,9 @@ export default {
|
|||||||
} else if (!this.processedData.length) {
|
} else if (!this.processedData.length) {
|
||||||
data = this.copyData
|
data = this.copyData
|
||||||
}
|
}
|
||||||
data = this.computePageDivideData(data)
|
if (this.pagination.custom !== true) {
|
||||||
|
data = this.computePageDivideData(data)
|
||||||
|
}
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
tableStl () {
|
tableStl () {
|
||||||
@ -442,9 +455,10 @@ export default {
|
|||||||
// },
|
// },
|
||||||
currentPage () {
|
currentPage () {
|
||||||
this.computeCurrentPageSelection()
|
this.computeCurrentPageSelection()
|
||||||
if (this.pagination.custom === true) {
|
// if (this.pagination.custom === true) {
|
||||||
this.useRemoteChange()
|
this.useRemoteChange()
|
||||||
}
|
this.mainTBodyEl.scrollTo(0, 0)
|
||||||
|
// }
|
||||||
|
|
||||||
// this.currentPageAllSelect = this.allCheckboxesSelect
|
// this.currentPageAllSelect = this.allCheckboxesSelect
|
||||||
this.$emit('on-page-change', this.paginationer)
|
this.$emit('on-page-change', this.paginationer)
|
||||||
@ -465,12 +479,13 @@ export default {
|
|||||||
currentSortColumn (sorter, oldSorter) {
|
currentSortColumn (sorter, oldSorter) {
|
||||||
this.processedData = this.computeShowingData()
|
this.processedData = this.computeShowingData()
|
||||||
// 上次的若是为custom,本次为locale sort那么也需要触发useRemoteChange
|
// 上次的若是为custom,本次为locale sort那么也需要触发useRemoteChange
|
||||||
if (
|
// if (
|
||||||
sorter.sorter === 'custom' ||
|
// sorter.sorter === 'custom' ||
|
||||||
(oldSorter && oldSorter.sorter === 'custom')
|
// (oldSorter && oldSorter.sorter === 'custom')
|
||||||
) {
|
// ) {
|
||||||
this.useRemoteChange()
|
// this.useRemoteChange()
|
||||||
}
|
// }
|
||||||
|
this.useRemoteChange()
|
||||||
this.$emit('on-sort-change', this.currentSortColumn)
|
this.$emit('on-sort-change', this.currentSortColumn)
|
||||||
},
|
},
|
||||||
checkBoxes () {
|
checkBoxes () {
|
||||||
@ -518,6 +533,15 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
// console.log(this.wrapperWidth, this.tbodyWidth)
|
// console.log(this.wrapperWidth, this.tbodyWidth)
|
||||||
|
this.columns.forEach((column, i) => {
|
||||||
|
if (column.defaultSortOrder) {
|
||||||
|
this.$set(
|
||||||
|
this.sortIndexs,
|
||||||
|
column.key || i,
|
||||||
|
sortOrderMap[column.defaultSortOrder]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.init()
|
this.init()
|
||||||
|
|
||||||
@ -546,7 +570,7 @@ export default {
|
|||||||
item => item !== currentEl && item !== null && item !== undefined
|
item => item !== currentEl && item !== null && item !== undefined
|
||||||
)
|
)
|
||||||
.forEach(el => {
|
.forEach(el => {
|
||||||
el.scrollTop = currentEl.scrollTop
|
if (currentEl) el.scrollTop = currentEl.scrollTop
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -595,21 +619,29 @@ export default {
|
|||||||
this.currentPage = pageNum
|
this.currentPage = pageNum
|
||||||
},
|
},
|
||||||
sort (columnKey, order) {
|
sort (columnKey, order) {
|
||||||
this.$set(this.sortIndexs, columnKey, order)
|
if (columnKey == null) {
|
||||||
|
this.clearSort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$set(this.sortIndexs, columnKey, sortOrderMap[order])
|
||||||
},
|
},
|
||||||
filter (filterOptions) {
|
filter (filterOptions) {
|
||||||
// ---- TODO: 未来版本将会去除这段代码,为了兼容老版本
|
// // ---- TODO: 未来版本将会去除这段代码,为了兼容老版本
|
||||||
Object.keys(filterOptions).forEach(key => {
|
// Object.keys(filterOptions).forEach(key => {
|
||||||
let column = this.columns.find(item => item.key === key)
|
// let column = this.columns.find(item => item.key === key)
|
||||||
if (column && !column.filterMultiple) {
|
// if (column && !column.filterMultiple) {
|
||||||
if (filterOptions[key].length) {
|
// if (filterOptions[key].length) {
|
||||||
filterOptions[key] = filterOptions[key][0]
|
// filterOptions[key] = filterOptions[key][0]
|
||||||
} else {
|
// } else {
|
||||||
delete filterOptions[key]
|
// delete filterOptions[key]
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
// ----
|
// // ----
|
||||||
|
if (filterOptions === null) {
|
||||||
|
this.selectedFilter = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
this.selectedFilter = filterOptions
|
this.selectedFilter = filterOptions
|
||||||
},
|
},
|
||||||
// search (columnKey,word) {
|
// search (columnKey,word) {
|
||||||
@ -651,7 +683,6 @@ export default {
|
|||||||
Object.keys(this.sortIndexs).forEach(key => {
|
Object.keys(this.sortIndexs).forEach(key => {
|
||||||
this.sortIndexs[key] = 0
|
this.sortIndexs[key] = 0
|
||||||
})
|
})
|
||||||
this.currentSortColumn = null
|
|
||||||
},
|
},
|
||||||
computeHorizontalScrollBarHeight () {
|
computeHorizontalScrollBarHeight () {
|
||||||
const tbody = this.mainTBodyEl
|
const tbody = this.mainTBodyEl
|
||||||
@ -756,45 +787,44 @@ export default {
|
|||||||
|
|
||||||
keys.forEach(key => {
|
keys.forEach(key => {
|
||||||
let val = this.currentFilterColumn[key].value
|
let val = this.currentFilterColumn[key].value
|
||||||
let filterFn = this.currentFilterColumn[key].filterFn
|
// let filterFn = this.currentFilterColumn[key].filterFn
|
||||||
let filterMultiple = this.currentFilterColumn[key].filterMultiple
|
// let filterMultiple = this.currentFilterColumn[key].filterMultiple
|
||||||
if (option === 'custom' && filterFn === 'custom') {
|
currentFilterColumn[key] = val
|
||||||
currentFilterColumn[key] = {
|
|
||||||
value: filterMultiple ? val : val[0]
|
|
||||||
}
|
|
||||||
} else if (option !== 'custom') {
|
|
||||||
currentFilterColumn[key] = {
|
|
||||||
value: filterMultiple ? val : val[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
if (Object.keys(currentFilterColumn).length === 0) {
|
if (Object.keys(currentFilterColumn).length === 0) {
|
||||||
currentFilterColumn = null
|
currentFilterColumn = null
|
||||||
}
|
}
|
||||||
return currentFilterColumn
|
return currentFilterColumn
|
||||||
},
|
},
|
||||||
getCustomSorterData () {
|
// getCustomSorterData () {
|
||||||
if (!this.currentSortColumn) {
|
// if (!this.currentSortColumn) {
|
||||||
return null
|
// return null
|
||||||
}
|
// }
|
||||||
const isCustom =
|
// const isCustom =
|
||||||
this.currentSortColumn.sorter === 'custom' &&
|
// this.currentSortColumn.sorter === 'custom' &&
|
||||||
this.currentSortColumn.type !== null
|
// this.currentSortColumn.type !== null
|
||||||
return isCustom ? this.currentSortColumn : null
|
// return isCustom ? this.currentSortColumn : null
|
||||||
},
|
// },
|
||||||
useRemoteChange () {
|
useRemoteChange () {
|
||||||
clearTimeout(this.remoteTimter)
|
clearTimeout(this.remoteTimter)
|
||||||
|
|
||||||
this.remoteTimter = setTimeout(() => {
|
this.remoteTimter = setTimeout(() => {
|
||||||
const currentFilterColumn = this.getFilterData('custom')
|
const currentFilterColumn = this.getFilterData('custom')
|
||||||
const currentSortColumn = this.getCustomSorterData()
|
const currentSortColumn = this.currentSortColumn
|
||||||
|
|
||||||
|
const sortType =
|
||||||
|
currentSortColumn && Number(currentSortColumn.type).toString()
|
||||||
const emitData = {
|
const emitData = {
|
||||||
filter: currentFilterColumn,
|
filter: currentFilterColumn || null,
|
||||||
sorter: {
|
sorter:
|
||||||
key: currentSortColumn.key,
|
currentSortColumn && currentSortColumn.type !== 0
|
||||||
order: currentSortColumn.type
|
? {
|
||||||
},
|
field: currentSortColumn.key,
|
||||||
pagination: this.paginationer
|
order: sortOrderReverseMap[sortType],
|
||||||
|
column: currentSortColumn.column
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
pagination: this.paginationer || null
|
||||||
// search: this.currentSearchColumn
|
// search: this.currentSearchColumn
|
||||||
}
|
}
|
||||||
this.$emit('on-change', emitData)
|
this.$emit('on-change', emitData)
|
||||||
@ -868,9 +898,9 @@ export default {
|
|||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
onFilter (value, column) {
|
onFilter (value, column) {
|
||||||
if (column.filter === 'custom') {
|
// if (column.filter === 'custom') {
|
||||||
this.useRemoteChange()
|
this.useRemoteChange()
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
onSortChange (sortIndexs) {
|
onSortChange (sortIndexs) {
|
||||||
this.sortIndexs = sortIndexs
|
this.sortIndexs = sortIndexs
|
||||||
|
@ -226,6 +226,8 @@
|
|||||||
border-radius: 2.5px;
|
border-radius: 2.5px;
|
||||||
background: $--table-scrollbar-color;
|
background: $--table-scrollbar-color;
|
||||||
}
|
}
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
|
||||||
tr.n-table__tr--hover {
|
tr.n-table__tr--hover {
|
||||||
background-color: $--table-row-hover;
|
background-color: $--table-row-hover;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user