Composition Api封裝業務hook思路示例分享

前序

近期公司的新項目一個小程序,一直想嘗試 Vue3 開發項目,苦於自己的驅動力不行,學的零零碎碎的。因此小程序我直接跟項目組長說我要使用 uniapp 的 Vue3 版進行開發。開發中遇到業務場景相同的,就分裝瞭一個hook 來減少代碼,易於維護。

hook的場景

這種獲取列表的需求很常見吧,在我這個小程序中有3處使用到瞭獲取列表的功能。分別是: 我的收藏、已投遞崗位、未投遞崗位。

當然展示崗位的 card 我是分裝瞭一個組件,很簡單的業務組件,這裡也不會描述。

假如: 我的收藏、已投遞崗位、未投遞崗位 都各自獲取列表,就會出現重復性的定義以下代碼

const getJobParameter = reactive<paramsType>({
    page: 1,
    pageSize: 10,
    code: null,
    releaseJobName: null,
  });
const jobList = ref([] as Array<jobType>);
const total = ref(0);
onLoad(() => {
    getlist();
  });
onReachBottom(() => {
    if (jobList.value.length < total.value) {
      getJobParameter.page++;
      getlist();
    }
});
async function getlist() {
    const res: any = await fn(getJobParameter);
    jobList.value = await [...jobList.value, ...res.data.data.dataList];
    total.value = res.data.data.total;
}

3個頁面都要寫上: 定義變量 -> 初始獲取 -> 獲取的代碼判斷 -> 底部觸發的代碼。因此就直接分裝瞭一個 hook。

useGetJobList

共同

import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import { ref, reactive } from 'vue';
import { jobType } from '@/types/job-hunting';
interface paramsType {
  page: number;
  pageSize: number;
  code: string | null;
  releaseJobName: string | null;
}
export function useGetJobList(fn) {
  const getJobParameter = reactive<paramsType>({
    page: 1,
    pageSize: 10,
    code: null,
    releaseJobName: null,
  });
  const jobList = ref([] as Array<jobType>);
  const total = ref(0);
  onLoad(() => {
    getlist();
  });
  onReachBottom(() => {
    if (jobList.value.length < total.value) {
      getJobParameter.page++;
      getlist();
    }
  });
  async function getlist() {
    const res: any = await fn(getJobParameter);
    jobList.value = await [...jobList.value, ...res.data.data.dataList];
    total.value = res.data.data.total;
  }
  async function refresh() {
    getJobParameter.page = 1;
    jobList.value = [];
    await getlist();
    return true;
  }
  return {
    jobList,
    refresh: () => refresh(),
  };
}

已上代碼就是簡單的獲取到崗位的 list 還未進行操作。

思路歷程

因為首頁有城市的選擇、崗位的搜索等功能。

下面是我開始時的想法(錯誤):

我想著要不把 getJobParameter 的參數全部暴露出去,然後對這些參數進行操作,但是內心感覺怪怪的,這樣跟不分裝好像區別也不大,又思考要不在 useGetJobList 加一個參數用來傳遞 參數的變化,當然這個也是行不通的。

後面看瞭別人分裝的 hook。就有瞭以下代碼。

import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import { ref, reactive } from 'vue';
import { jobType } from '@/types/job-hunting';
interface paramsType {
  page: number;
  pageSize: number;
  code: string | null;
  releaseJobName: string | null;
}
export function useGetJobList(fn) {
  const getJobParameter = reactive<paramsType>({
    page: 1,
    pageSize: 10,
    code: null,
    releaseJobName: null,
  });
  const jobList = ref([] as Array<jobType>);
  const total = ref(0);
  onLoad(() => {
    getlist();
  });
  onReachBottom(() => {
    if (jobList.value.length < total.value) {
      getJobParameter.page++;
      getlist();
    }
  });
  async function getlist() {
    const res: any = await fn(getJobParameter);
    jobList.value = await [...jobList.value, ...res.data.data.dataList];
    total.value = res.data.data.total;
  }
  async function refresh() {
    getJobParameter.page = 1;
    jobList.value = [];
    await getlist();
    // 這個後面的代表異步瞭
    return true;
  }
  function reset () {
    getJobParameter.page = 1;
    getJobParameter.code = null;
    getJobParameter.releaseJobName = null;
  }
  function queryList(searchValue: string | null) {
    reset();  
    getJobParameter.releaseJobName = searchValue;
    getlist();
  }
  function codeChange(code: string | null) {
    reset(); 
    getJobParameter.code = code;
    getlist();
  }
  return {
    jobList,
    queryList: (searchValue: string | null) => queryList(searchValue),
    codeChange: (code: string | null) => codeChange(code),
    refresh: () => refresh(),
  };
}

這裡為 重新定兩個函數 分別是 queryList、codeChange,用來搜索和城市code 改變再獲取 崗位列表。

queryList: (searchValue: string | null) => queryList(searchValue), 
codeChange: (code: string | null) => codeChange(code),

上面代碼還有一個心得,就是在 return 是可以直接把函數寫為什麼要再分裝一個函數出來?

心得

  • 當定義瞭一個 hook , 當外部使用想改變 hook 內部的變量,內部寫個函數暴露出去,函數的內部是對變量的修改,外部隻需要使用暴露函數。這樣代碼十分的清晰易懂。
  • return 再分裝一個函數 是為瞭後期別人看代碼是可以一眼就知道返回哪些是變量,哪些是函數,函數有哪些參數,參數的類型等之類的,不用一個的去查找。

utils 和 hook 的區別

之前我一直搞不清楚 hook 和 utils 的區別,我感覺差不多都是分裝一個函數出來。

區別: utils 是一個簡單的參數傳入,然後返回,返回的變量不具有響應式。沒有使用到 Vue 的 reactive、ref等鉤子函數, 我認為當你使用瞭這些鉤子函數就可以說它是一個 hook。

總結

hook 有點想面向對象的語言的 class, 內部定義的變量,最好自己內部的做處理,隻需暴露出一個函數。

  • 當定義瞭一個 hook , 當外部使用想改變 hook 內部的變量就因此寫一個函數暴露出去,進行變量的更改
  • return 再分裝一個函數 是為瞭後期別人看代碼是可以一眼就知道返回哪些是變量,哪些是函數,函數有哪些參數,參數的類型等之類的,不用一個的去查找。

以上就是Composition Api封裝業務hook思路示例分享的詳細內容,更多關於Composition Api封裝hook的資料請關註WalkonNet其它相關文章!

推薦閱讀: