プロジェクトのシナリオ
小さなプログラムや h5 などのモバイル端末を作成したことがある人なら、バックグラウンド リスト インターフェイスを要求するときにページングが発生することを知っています。
ページネーションの利点
- 1. インターフェースの応答速度を向上させます (ご存知のとおり、10 個のデータをチェックするのと 10,000 個のデータをチェックするのでは、応答時間に明らかに違いがあります)
- 2. フロントエンドのレンダリングパフォーマンスを向上させ、すべてのデータを一度に検出します. 仮想リストを作成しない場合、フロントエンドはフリーズします。
- 3. サーバーの負荷を軽減
提起された質問
Xiaosheng Bibi: サーバーへの負荷が軽減されました。コードの量が増加しました。各ページは、現在のリストのステータス (次のページがあるかどうか)、現在のリストがどのページであるかを定義する必要があります。 1 ページあたりのリクエストの数! 私はただの下手なプログラマーです。ただ早く仕事を終えたいだけです。!特に 1 つのページで複数のリストを要求する場合、これらのコードを繰り返し記述するのは非常に面倒ですよね。
では、たった 1 行のコードでこれらの繰り返されるパラメーターを再利用するにはどうすればよいでしょうか? ? フックを使用して解決できます
以前の練習
タイプを定義する
リクエストメソッドを記述し、リストデータとステータスを設定する
現在の習慣
タイプ+リクエストメソッドを定義
とても簡単なので、使うだけで完了です
フックの由来
フックは React 16.8.0 の新機能です。私はたまたまその時に React を書いていました。React を書いたことがある人なら誰でも知っていると思いますが、当時はクラス コンポーネントが主流であり、フックは
なんてこった?? 使いやすいですか?フックがどのような問題を解決するかを見てみましょう。
-
1. コンポーネント間で状態ロジックを再利用するのが難しい
-
2. 複雑なコンポーネントの理解が困難になる
-
3. 理解できないクラス (上記のクラスコンポーネント)
しばらく使ってみて、これは本当に使いやすく、クラスコンポーネントよりもずっと書きやすく、導入するだけで使えると感じました。
Vue3: React、皆さんはフックについて良いアイデアを持っています。私がそれを使ってみましょう
現時点では、vue3 にはさまざまなフックもあります。
カスタムフック
フックの名前は一般的に useXXXXX です。さまざまなフックが含まれている vue 公式フック ライブラリ vueUses をお勧めします。残念ながらこのライブラリは英語のドキュメントですが、大きな問題はありません。使いやすさには全く影響ありません
vueUses公式サイトアドレス
インターフェース関数の例と応答例
export interface IListResponse<T> {
code: number
rows: T,
msg: string,
[key: string]: any
}
export type TApiListRequest<T> = Promise<IListResponse<T>>
/**
* 客户列表
* @param params
* @returns
*/
export const reqCustomerlistPage = <T>(params?: T): TApiListRequest<ICustomerListItem[]> => {
return new Promise(async (resolve) => {
const url = `/core/customer/listPage`;
let result = await $http.post(url, params);
resolve(result);
});
};
カスタムフックのリストリクエストコード
interface IUseRequestListConfig<T> {
/** 当前页自定义请求字段,默认是pageNum */
pageNumFields?: string
/** 每页数量自定义请求字段,默认是pageSize */
pageSizeFields?: string
/** 返回数据中列表的字段,默认是rows */
dataFields?: string
/**封装好的接口api */
apiFunction: (params?: any) => TApiListRequest<T[]>
}
// 加载状态
enum TLoadStatus {
LOAD_MORE = 'loadmore', //# 加载更多
LOADING = 'loading', //#加载中
NOMORE = 'nomore', //#没有更多
}
/**
* 列表请求hooks
* @param originConfig 配置
* @returns
*/
export const useRequestList = <T>(originConfig: IUseRequestListConfig<T>) => {
// 默认配置
const defaultConfig = {
pageNumFields: "pageNum", pageSizeFields: "pageSize", dataFields: "rows" }
// 合并后配置
const config: IUseRequestListConfig<T> = {
...defaultConfig, ...originConfig }
interface IState {
params: {
[x: string]: number;
};
}
const state = reactive<IState>({
params: {
[config.pageNumFields!]: 1,
[config.pageSizeFields!]: 10,
},
})
const dataSource = ref<T[]>([])
const status = ref<TLoadStatus>(TLoadStatus.LOAD_MORE)
/**
* 加载数据
* @param otherParams
* @returns
*/
const loadData = async <T extends Record<string, unknown>>(otherParams?: T) => {
if (status.value === TLoadStatus.NOMORE) return;
status.value = TLoadStatus.LOADING;
let result = await config.apiFunction({
...state.params, ...otherParams });
if (state.params.pageNum === 1) dataSource.value = [];
state.params.pageNum += 1;
dataSource.value = [...dataSource.value, ...result[config.dataFields!]];
status.value = dataSource.value.length < result.total ? TLoadStatus.LOAD_MORE : TLoadStatus.NOMORE;
}
/**
* 刷新列表
* beforeRfresh用于在刷新之前清空某些查询字段
*/
const handleRefresh = async <T extends Record<string, unknown>>(otherParams?: T, beforeRfresh?: () => void) => {
beforeRfresh?.()
status.value = TLoadStatus.LOAD_MORE;
state.params = {
...state.params,
[config.pageNumFields!]: 1,
};
await loadData(otherParams);
};
return {
loadData,
dataSource,
status,
handleRefresh
}
}
説明書
const {
handleRefresh, loadData, status, dataSource } = useRequestList({
apiFunction: reqCustomerlistPage });
そうです、リストのリクエストは 1 行のコードで実行できます (これでようやく楽しく釣りができます)。
使用中は、リクエストする必要があるライフサイクルのフック メソッドとフック関数をスローするだけです。このフックでは、返されるデータが現在のリストのステータスは応答性です。リストの下部にあるコンポーネントをさらにロードするには、TLoadStatus 列挙体を変更して現在のステータスを指定する必要があります。一部のコンポーネント ライブラリのロード ステータスは、0、1、2、および私のような人もいるかもしれません。