組合函數(shù)實(shí)現(xiàn)代碼復(fù)用

最近在 Vue.js 項(xiàng)目重構(gòu)中,體會到了 Composable 的代碼復(fù)用價值. 這里梳理一下.

業(yè)務(wù)中, 很常見的 CRUD 需求主要有如下通用的構(gòu)成:

界面

  1. 數(shù)據(jù)列表
  2. 新增按鈕
  3. 每行數(shù)據(jù)對應(yīng) 1 個編輯按鈕
  4. 每行數(shù)據(jù)對應(yīng) 1 個刪除按鈕

功能

  1. 頁面加載時, 獲取列表數(shù)據(jù)(帶有 loading 指示)
  2. 點(diǎn)擊新增或者編輯按鈕時, 能夠彈出表單.
  3. 修改相應(yīng)的表單后, 列表數(shù)據(jù)需要更新.
  4. 點(diǎn)擊刪除按鈕, 能夠給出數(shù)據(jù)刪除提醒.
  5. 刪除之后, 列表數(shù)據(jù)隨之更新.
  6. 如果數(shù)據(jù)操作出現(xiàn)異常,給出彈窗反饋.
  7. 數(shù)據(jù)上傳成功, 給出彈窗反饋.

之前每開發(fā)一個功能時, 上面的過程幾乎都要走一遍, 雖然難度不大, 但過程枯燥,容易遺漏犯錯. 而采用 Composable 之后, 上面的邏輯完全可以抽離出來,形成一個組合函數(shù) useList

import { onMounted, ref, watch } from "vue";  
import { Dialog, Notify } from "quasar";

export function useList(actions) {  
  const loading = ref(false);  
  const list = ref([]);  
  const formVisible = ref(false);  
  
  const openForm = () => {  
    formVisible.value = true;  
  };  
  
  const loadData = async () => {  
    loading.value = true;  
    try {  
      list.value = await actions.getList();  
    } catch (error) {  
      console.error(error);  
    } finally {  
      loading.value = false;  
    }  
  };  
  
  const deleteFn = async (id) => {  
    Dialog.create({  
      title: "提醒",  
      message: "確認(rèn)刪除?",  
      ok: {  
        unelevated: true,  
        color: "negative",  
      },  
      cancel: {  
        flat: true,  
        color: "black",  
      },  
      persistent: true,  
    }).onOk(async () => {  
      try {  
        await actions.deleteItem(id);  
        Notify.create({  
          message: "刪除成功",  
          type: "positive",  
        });  
        const index = list.value.findIndex((el) => el.id === id);  
        if (index !== -1) {  
          list.value.splice(index, 1);  
        }  
      } catch (error) {  
        Notify.create({  
          message: "刪除失敗",  
          type: "negative",  
        });  
      }  
    });  
  };  
  
  const updateList = async (data) => {  
    const index = list.value.findIndex((el) => el?.id === data.id);  
    if (index !== -1) {  
      list.value.splice(index, 1, data);  
    } else {  
      // 新增  
      list.value.splice(0, 0, data);  
    }  
  };  
  
  onMounted(() => loadData());  
  
  return {  
    loading,  
    list,  
    formVisible,  
    openForm,  
    deleteFn,  
    updateList,  
  };  
}

應(yīng)用

面對一個新的CRUD業(yè)務(wù)時, 只用定義好 actions 參數(shù), 然后調(diào)用 useList 即可獲得頁面所需要的全部數(shù)據(jù).

// actions 參數(shù)給出了獲取列表,刪除列表的方法.
const actions = {  
  getList: async () => await api.get(some_url),  
  deleteItem: async (id) => await api.delete(some_url + id + "/"),  
};
// 調(diào)用組合函數(shù)
const {  
  loading,  
  formVisible,  
  list,  
  openForm,  
  deleteFn,  
  updateList,  
} = useList(actions);

借助 Quasar 實(shí)現(xiàn)組件視圖模板:

<q-card>  
  <q-table  
    :data="list"  
    :loading="loading"  
  >  
    <template v-slot:top>  
      <q-btn  
        :disable="loading"  
        label="新增"  
        @click="openForm"  
      />  
    </template>   
    <template v-slot:body-cell-id="props">  
      <q-td :props="props">  
        <q-btn label="編輯" @click="openForm(props.row)" />  
        <q-btn label="刪除" @click="deleteFn(props.row.id)"/>  
      </q-td>  
    </template>  
  </q-table>  
  <meeting-assign-form-modal 
      v-model="formVisible" 
      @update="updateList" />  
</q-card>

短短幾十行代碼, 就能實(shí)現(xiàn)一個功能完備的列表頁.

可以按照此邏輯, 編寫自己的useForm組合函數(shù), 實(shí)現(xiàn)表單頁面的通用邏輯抽離. 這樣開發(fā)效率將大大提高. 而且, 令人興奮的是, 不僅僅是Vue.js 3支持組合函數(shù), Vue.js 2.7也同樣支持上述寫法.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敲董,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌第练,老刑警劉巖沉唠,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糯笙,死亡現(xiàn)場離奇詭異惧蛹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)志珍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門橙垢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伦糯,你說我怎么就攤上這事柜某。” “怎么了敛纲?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵喂击,是天一觀的道長。 經(jīng)常有香客問我淤翔,道長翰绊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任旁壮,我火速辦了婚禮监嗜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抡谐。我一直安慰自己裁奇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布麦撵。 她就那樣靜靜地躺著刽肠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪免胃。 梳的紋絲不亂的頭發(fā)上音五,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機(jī)與錄音羔沙,去河邊找鬼躺涝。 笑死,一個胖子當(dāng)著我的面吹牛撬碟,可吹牛的內(nèi)容都是我干的诞挨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼呢蛤,長吁一口氣:“原來是場噩夢啊……” “哼惶傻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起其障,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤银室,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后励翼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜈敢,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年汽抚,在試婚紗的時候發(fā)現(xiàn)自己被綠了抓狭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡造烁,死狀恐怖否过,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惭蟋,我是刑警寧澤苗桂,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站告组,受9級特大地震影響煤伟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜木缝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一便锨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧我碟,春花似錦鸿秆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恳守,卻和暖如春考婴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背催烘。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工沥阱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伊群。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓考杉,卻偏偏與公主長得像策精,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崇棠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354