More articles
preface
To continue the combined API, today we share useTable. In fact, we have shared useTable before, but there is no business verification. After a period of business practice, here we share a version more complete than before
introduce
UseTable is the encapsulation of the basic logic of the list class. UI representation may be in the form of table, list, etc. Extensions such as useTableEdit, useTableColumn, etc. are completed on the basis of useTable. In addition, lists and paging information follow each other. So useTable contains paging information
Based on using
<template> <div> <Table :dataSource="dataSource" :columns="columns" :loading="loading" /> <Pagination :pagination="pagination" /> </div> </template> <script> import Table from '@/components/table' import Pagination from '@/components/qjd/pagination' import useTable from '@/hooks/useTable' import { columns } from './config' export default { components: {Table, Pagination}, setup() {Table dataSource: Pagination, request: Const {dataSource, pagination, loading} = useTable({request}) return {dataSource, pagination, loading, columns } } } </script>Copy the code
Initialization is not called
For some scenarios that do not need to trigger an interface call during initialization, set isInit to false. The default is true
const { dataSource } = useTable({ request, isInit: false })
Copy the code
The default parameters
Default initialization parameters can be set using defaultParams. Default is {}.
const { dataSource } = useTable({ request, defaultParams: { id: 1}})Copy the code
Is there pagination
IsPage defaults to true and is set to false if pagination is not required
const { dataSource } = useTable({ request, isPage: false })
Copy the code
The interface returned invalid data. Procedure
According to the convention, usually the data returned by the back end conforms to the processing of useTable, but does not exclude the case that does not comply, the data can be processed through callback
The returned data must be in the {totalCount, dataSource} format
const { dataSource } = useTable({
request,
callback: ({ code, data }) = > {
return code === '0' ? { totalCount: data? .total ||0.dataSource: data? .data || [] } : {} } })Copy the code
Dynamic header
When the header is dynamic, the incoming parameter needs to pass a column and isActiveColumn, and the outgoing parameter needs to pass another reactive column and the method setColumns to update the reactive data. IsActiveColumn tells useTable to mix useTableColumn logic
const {
columns,
dataSource,
setColumns
} = useTable({
request,
isActiveColumn: true.columns: defaultColumns
})
// Set the table header
const changeColumns = cols = > setColumns(cols)
Copy the code
Editable table
When a paginated list is edited without a real-time request from the back end to store data, the edited data will be lost when switching paginated request data, and editable table is the solution to this problem. Like dynamic table headers, editable tables do not belong to the basic table function. You need to pull a separate use function to complete the table and mix it with useTable through input methods
Setting Edit to true tells useTable to blend in the useTableEdit logic
const { dataSource, setEditChange } = useTable({ request, edit: true })
// If the table has an input and the event that listens for changes in the input data is onChange, then the edit data can be stored when the onChange event is triggered
// setEditChange: Stores the current edited data. After storing the data, the page will carry the previously edited data when switching
const onChange = () = > setEditChange(dataSource)
Copy the code
Pops up the table
If you want to use a custom checkbox, you can use a new use function to retrieve the original checkbox logic (annotated in the useTableCheckBox). Multi-select tables are also not part of the basic table function. To cope with paging switching, Element provides this function. Reserve-selection is optional
Set checkbox to true to enable multiple selection
const { dataSource, selectionChange } = useTable({ request, checkbox: true })
// Set selectionHandle to the selection-change event of element-table
const selectionHandle = vals= > selectionChange(vals)
Copy the code
The source code
All the logic that does not belong to the basic table function is implemented by a separate use function. In the introduction of useTable, only the logic related to the basic table is released
import { reactive, toRefs, ref, onUnmounted } from '@vue/composition-api'
import { deepCopy } from '@/utils/qjd'
import useAsync from './useAsync'
// Dynamic table header - logic
import useTableColumn from './useTableColumn'
/ / the checkbox - logic
import useTableCheckBox from './useTableCheckBox'
// edit table- logic
import useTableEdit from './useTableEdit'
/** Applies to general table & page, with components/ QJD /table and Pagination. Currently, the component is only used in the development of the scene, what is missing is added, according to the actual scene extension useTbale *@param Request Interface or Array<any> *@param DefaultParams is the default entry parameter *@param IsInit whether to initialize the call *@param IsPage is paged *@param Checkbox Specifies whether to enable multiple select mode and mix multiple select logic *@param Edit Whether to enable edit mode and blend in edit logic *@function Callback Provides a fault tolerance mechanism * if the interface does not return sufficient data@param Columns need to be entered if the columns are dynamic headers. The useTable header is used later. If the columns are static, * is not required@param IsActiveColumn Whether to enable dynamic form mode */
const defaultCallBack = (data = {}) = > {
const { totalCount = 0, pagedRecords = [] } = data || {}
return {
totalCount,
dataSource: pagedRecords
}
}
function useTable({
request,
defaultParams = {},
isInit = true,
isPage = true,
checkbox = false,
edit = false,
callback = defaultCallBack,
columns = [],
isActiveColumn = false
}) {
const c = defaultParams && defaultParams.current ? defaultParams.current : 1
const p = defaultParams && defaultParams.pageSize ? defaultParams.pageSize : 10
const current = ref(c)
const pageSize = ref(p)
// Store the anti-shake function
const timer = ref(null)
const state = reactive({
params: isPage ? Object.assign({ page: current, pageSize: pageSize }, defaultParams) : defaultParams,
searchInfo: {},
dataSource: [].pagination: {
current: current,
pageSize: pageSize,
total: 0.onChange: (page, pageSize) = > pageChange(page, pageSize),
onShowSizeChange: (current, size) = > showSizeChange(current, size)
}
})
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert dynamic header logic start -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
// Insert the useTableColumn logic here
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert dynamic header logic end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert the checkbox multi-select logic start -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
// Insert useTableCheckBox logic here
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert the checkbox multi-select logic end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert editable table logic start -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
// Insert useTableEdit logic here
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert editable table logical end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
// Successful callback
const successCallBack = ({ code, data }) = > {
if (code === '0') {
// Callback processes data
const result = callback ? callback(data) : data
const { totalCount = 0, dataSource = [] } = result || {}
state.pagination.total = totalCount || (dataSource ? dataSource.length : 0)
state.dataSource = dataSource
// Echo data in edit mode
edit && setEditDataSource(state.dataSource, current.value)
}
}
/ / interface
const { doResult, loading } = useAsync({
request,
init: false.params: {},
successCallBack
})
// API request or JSON
const _request = (params = {}) = > {
if (Object.prototype.toString.call(request) === '[object Array]') { // Use the JSON data passed in at definition
state.dataSource = request
state.pagination.total = request.length
} else if (Object.prototype.toString.call(request) === '[object Function]') { // Use the API request passed in when the definition is useddoResult({ ... state.params, ... params }) } }/ / query
const searchHandle = (searchInfo = {}) = > {
// Copy data to prevent upper-layer data from being affected
searchInfo = deepCopy(searchInfo)
current.value = c
pageSize.value = p
state.pagination.current = searchInfo.page ? searchInfo.page : c
state.pagination.pageSize = searchInfo.pageSize ? searchInfo.pageSize : p
state.searchInfo = searchInfo
_request(searchInfo)
}
// If the current page is not the first page and the data after the switch is only one page, pageChange will be triggered after showSizeChange is triggered
const _deferRequest = () = > {
timer.value && clearTimeout(timer.value)
timer.value = setTimeout(() = > {
_request(state.searchInfo)
}, 0)}// Toggle pages
const pageChange = (page, pageSize) = > {
current.value = page
state.searchInfo.page = page
_deferRequest()
}
// Switch the number of entries
const showSizeChange = (current, size) = > {
pageSize.value = current
state.searchInfo.pageSize = current
_deferRequest()
}
/ / reset
const resetHandle = () = > {
state.searchInfo = {}
current.value = c
pageSize.value = p
_request({})
}
// Clear the data
const clearHandle = () = > {
state.dataSource = []
current.value = c
pageSize.value = p
}
// Initialize the data
isInit && _request(state.params)
// Clear the timer
onUnmounted(() = > {
if (timer.value) {
clearTimeout(timer.value)
timer.value = null}})return {
...toRefs(state),
loading,
searchHandle,
resetHandle,
clearHandle,
// checkbox Select multiple states & interfaces. checkBoxParams,// Edit table status & interface. editParams,// Dynamic table header related state & interface. activeColParams, } }export default useTable
Copy the code
The ginseng
parameter | instructions | type | An optional value | The default value |
---|---|---|---|---|
request | Interface request | Promise | – | – |
defaultParams | The interface requests the default input parameter | Object | – | {} |
isInit | Whether to initiate an interface request | Boolean | – | true |
isPage | Is there pagination | Boolean | – | true |
callback | The interface requests a data processing callback | Function(data) | – | – |
columns | To dynamic the header, you need to pass columns, referring to element | Arrary | – | [] |
isActiveColumn | Whether to enable the dynamic table header | Boolean | – | false |
checkbox | Whether to enable multiple selection | Boolean | – | false |
edit | Whether to enable table editable | Boolean | – | false |
The ginseng
parameter | instructions | type | An optional value | The default value |
---|---|---|---|---|
dataSource | Interface request data | Arrary | – | [] |
pagination | The paging information | Object | – | – |
searchInfo | Query conditions | Object | – | {} |
loading | Loading status | Boolean | – | false |
searchHandle | Actively triggers the interface to invoke a method | Function(params) | – | – |
resetHandle | Reset (Reset query criteria &dataSource) | Function | – | – |
clearHandle | Clear data & reset paging information | Function | – | – |
Pagination
key | instructions | The default value |
---|---|---|
current | The current number of pages | 1 |
pageSize | The current article number | 10 |
total | The total number of article | 0 |
onChange | Page number change event | Function(page, pageSize) |
onShowSizeChange | Number change event | Function(current, size) |
The outgoing parameter added after isActiveColumn is enabled
parameter | instructions | type | An optional value | The default value |
---|---|---|---|---|
columns | The columns configuration | Arrary | – | [] |
setColumns | Set up the columns | Function(data) | – | – |
Enable the checkbox output parameter
parameter | instructions | type | An optional value | The default value |
---|---|---|---|---|
currentSelects | Currently selected data | Arrary | – | [] |
setCurrentSelects | Set the currentSelects | Function(data) | – | – |
selectionChange | If currentSelects is set, checkBox is not enabled | Function(data) | – | – |
Enable the output parameter added after Edit
SetEditChange is the key to the data echo. This method is triggered to set the editDatas after the data is edited to ensure that the data can be displayed properly during the page switch
parameter | instructions | type | An optional value | The default value |
---|---|---|---|---|
editDatas | Edit the data | Object | – | {} |
clearEdits | Clearing edit data | Function | – | – |
setEditChange | Set edit data | Function(data: any[]) | – | – |
conclusion
Table function is quite complex, there will be part of the logic away, mainly depends on the business encountered what kind of requirements, here to complete the packaging of this part of the logic in direct use will be good, the next article to share useForm