124124</template >
125125
126126<script setup lang="ts">
127- import { ref , computed , useTemplateRef , watch , shallowRef , toRef } from ' vue' ;
127+ import { ref , computed , useTemplateRef , watch , onMounted } from ' vue' ;
128128 import SkeleteLoader from ' @/components/SkeleteLoader.vue' ;
129129 import { IconTableRowOutline } from ' @iconify-prerendered/vue-flowbite' ;
130130
131131 defineExpose ({
132132 refreshTable
133133 })
134134
135- type Row = Record <string , unknown >
136- type LoadFn = (params : { offset: number , limit: number }) => Promise <{ data: Row []; total: number }>
137-
138- const isFunc = (v : unknown ): v is LoadFn => typeof v === ' function'
139-
140- function usePagedData(props : {
141- data: Row [] | LoadFn
142- pageSize: number
143- currentPage: number
144- }) {
145- const page = ref (props .currentPage )
146- const pageSize = toRef (props , ' pageSize' )
147-
148- const isLoading = ref (false )
149- const error = shallowRef <unknown >(null )
150- const result = shallowRef <{ data: Row []; total: number }>({ data: [], total: 0 })
151-
152- let requestId = 0
153-
154- async function fetchData() {
155- const id = ++ requestId
156- isLoading .value = true
157- error .value = null
158- try {
159- if (isFunc (props .data )) {
160- const res = await props .data ({offset: ((page .value - 1 ) * pageSize .value ), limit: pageSize .value })
161- if (id !== requestId ) return
162- result .value = res
163- } else {
164- const start = (page .value - 1 ) * pageSize .value
165- const end = start + pageSize .value
166- result .value = { data: props .data .slice (start , end ), total: props .data .length }
167- }
168- } catch (e ) {
169- if (id !== requestId ) return
170- error .value = e
171- result .value = { data: [], total: 0 }
172- } finally {
173- if (id === requestId ) isLoading .value = false
174- }
175- }
176-
177- watch ([page , pageSize , () => props .data ], fetchData , { immediate: true })
178-
179- return { page , pageSize , isLoading , error , result , refresh: fetchData }
180- }
181-
182135 const props = withDefaults (
183136 defineProps <{
184137 columns: {
196149 }
197150 );
198151
199- const { result : dataResult, isLoading, error, page : currentPage, pageSize, refresh } = usePagedData ({
200- data: props .data ,
201- pageSize: props .pageSize ,
202- currentPage: 1
203- });
204-
205152 const pageInput = ref (' 1' );
206153 const rowRefs = useTemplateRef <HTMLElement []>(' rowRefs' );
207154 const headerRefs = useTemplateRef <HTMLElement []>(' headerRefs' );
208155 const rowHeights = ref <number []>([]);
209156 const columnWidths = ref <number []>([]);
157+ const currentPage = ref (1 );
158+ const isLoading = ref (false );
159+ const dataResult = ref <{data: {[key : string ]: any }[], total: number }>({data: [], total: 0 });
160+
161+ onMounted (() => {
162+ refresh ();
163+ });
164+
165+ watch ( currentPage , async () => {
166+ refresh ();
167+ });
168+
210169
211170 watch (() => currentPage .value , () => {
212171 rowHeights .value = ! rowRefs .value ? [] : rowRefs .value .map ((el : HTMLElement ) => el .offsetHeight );
218177 });
219178
220179 const dataPage = computed (() => {
221- return dataResult .value .data ;
180+ return dataResult .value ? .data ;
222181 });
223182
224183 function switchPage(p : number ) {
258217 }
259218 }
260219
220+ function refresh() {
221+ if (typeof props .data === ' function' ) {
222+ isLoading .value = true ;
223+ props .data ({ offset: (currentPage .value - 1 ) * props .pageSize , limit: props .pageSize }).then ((result ) => {
224+ isLoading .value = false ;
225+ dataResult .value = result ;
226+ });
227+ } else {
228+ const start = (currentPage .value - 1 ) * props .pageSize ;
229+ const end = start + props .pageSize ;
230+ dataResult .value = { data: props .data .slice (start , end ), total: props .data .length };
231+ }
232+ }
233+
261234 function refreshTable() {
262235 currentPage .value = 1 ;
263- refresh ();
264236 }
265237
266238 </script >
0 commit comments