亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Vue中如何避免濫用watch

 更新時(shí)間:2024年03月01日 08:32:20   作者:前端歐陽(yáng)  
這篇文章主要為大家詳細(xì)介紹了Vue中濫用watch帶來(lái)的問(wèn)題以及如何解決,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

上周五晚上8點(diǎn),開(kāi)開(kāi)心心的等著產(chǎn)品驗(yàn)收完畢后就可以順利上線(xiàn)。結(jié)果產(chǎn)品突然找到我說(shuō)要加需求,并且維護(hù)這一塊業(yè)務(wù)的同事已經(jīng)下班走了,所以只有我來(lái)做。雖然內(nèi)心一萬(wàn)頭草泥馬在狂奔,但是嘴里還是一口答應(yīng)沒(méi)問(wèn)題。由于這一塊業(yè)務(wù)很復(fù)雜并且我也不熟悉,加上還餓著肚子,在梳理代碼邏輯的時(shí)候我差點(diǎn)崩潰了。需要修改的那個(gè)vue文件有幾千行代碼,迭代業(yè)務(wù)對(duì)應(yīng)的ref變量有10多個(gè)watch。我光是梳理這些watch的邏輯就搞了很久,然后小心翼翼的在原有代碼上面加上新的業(yè)務(wù)邏輯,不敢去修改原有邏輯(擔(dān)心搞出線(xiàn)上bug背鍋)。

濫用watch帶來(lái)的問(wèn)題

首先我們來(lái)看一個(gè)例子:

<template>
  {{ dataList }}
</template>

<script setup lang="ts">
import { ref, watch } from "vue";

const dataList = ref([]);
const props = defineProps(["disableList", "type", "id"]);
watch(
  () => props.disableList,
  () => {
    // 根據(jù)disableList邏輯很復(fù)雜同步計(jì)算出新list
    const newList = getListFromDisabledList(dataList.value);
    dataList.value = newList;
  },
  { deep: true }
);
watch(
  () => props.type,
  () => {
    // 根據(jù)type邏輯很復(fù)雜同步計(jì)算出新list
    const newList = getListFromType(dataList.value);
    dataList.value = newList;
  }
);
watch(
  () => props.id,
  () => {
    // 從服務(wù)端獲取dataList
    fetchDataList();
  },
  { immediate: true }
);
</script>

上面這個(gè)例子在template中渲染了dataList,當(dāng)props.id更新時(shí)和初始化時(shí)從服務(wù)端異步獲取dataList。當(dāng)props.disableListprops.type更新時(shí),同步的計(jì)算出新的dataList。

代碼邏輯流程圖是這樣的:

乍一看上面的代碼沒(méi)什么問(wèn)題,但是當(dāng)一個(gè)不熟悉這一塊業(yè)務(wù)的新同學(xué)接手這一塊代碼時(shí)問(wèn)題就出來(lái)了。

我們平時(shí)接手一個(gè)不熟悉的業(yè)務(wù)首先要找一個(gè)切入點(diǎn),對(duì)于前端業(yè)務(wù),切入點(diǎn)肯定是瀏覽器渲染的頁(yè)面。在 Vue 中,頁(yè)面由模板渲染而來(lái),找到模板中使用的響應(yīng)式變量和他的來(lái)源,就能理解業(yè)務(wù)邏輯。以 dataList 變量為例,梳理dataList的來(lái)源基本就可以理清業(yè)務(wù)邏輯。

在我們上面的這個(gè)例子dataList的來(lái)源就是發(fā)散的,有很多個(gè)來(lái)源。首先是watchprops.id從服務(wù)端異步獲取。然后是watchprops.disableListprops.type,同步更新了dataList。這個(gè)時(shí)候一個(gè)不熟悉業(yè)務(wù)的同學(xué)接到產(chǎn)品需求要更新dataList的取值邏輯,他需要先熟悉dataList多個(gè)來(lái)源的取值邏輯,熟悉完邏輯后再分析我到底應(yīng)該是在哪個(gè)watch上面去修改業(yè)務(wù)邏輯完成產(chǎn)品需求。

但是實(shí)際上我們維護(hù)別人的代碼時(shí)(特別是很復(fù)雜的代碼)一般都不愿意去改代碼,而是在原有代碼的基礎(chǔ)上再去加上我們的代碼。因?yàn)槿ジ膭e人的復(fù)雜代碼很容易搞出線(xiàn)上bug,然后背鍋。所以在這里我們的做法一般都是再加一個(gè)watch,然后在這個(gè)watch中去實(shí)現(xiàn)產(chǎn)品最新的dataList業(yè)務(wù)邏輯。

watch(
  () => props.xxx,
  () => {
    // 加上產(chǎn)品最新的業(yè)務(wù)邏輯
    const newList = getListFromXxx(dataList.value);
    dataList.value = newList;
  }
);

迭代幾次業(yè)務(wù)后這個(gè)vue文件里面就變成了一堆watch,屎山代碼就是這樣形成的。當(dāng)然不排除有的情況是故意這樣寫(xiě)的,為的就是穩(wěn)定自己在團(tuán)隊(duì)里面的地位,因?yàn)殡x開(kāi)了你這坨代碼沒(méi)人敢動(dòng)。

使用computed解決問(wèn)題

我們看了上面的反例,那么一個(gè)易維護(hù)的代碼是怎么樣的呢?我認(rèn)為應(yīng)該是下面這樣的:

dataListtemplate中渲染,然后同步更新dataList,最后異步從服務(wù)端異步獲取dataList,整個(gè)過(guò)程能夠被穿成一條線(xiàn)。此時(shí)新來(lái)一位同學(xué)要去迭代dataList相關(guān)的業(yè)務(wù),那么他只需要搞清楚產(chǎn)品的最新需求是應(yīng)該在同步階段去修改代碼還是異步階段去修改代碼,然后在對(duì)應(yīng)的階段去加上對(duì)應(yīng)的最新代碼即可。

我們來(lái)看看上面的例子應(yīng)該怎么優(yōu)化成易維護(hù)的代碼,上面的代碼中dataList來(lái)源主要分為同步來(lái)源和異步來(lái)源。異步來(lái)源這一塊我們沒(méi)法改,因?yàn)閺臉I(yè)務(wù)上來(lái)看props.id更新后必須要從服務(wù)端獲取最新的dataList。我們可以將同步來(lái)源的代碼全部摞到computed中。優(yōu)化后的代碼如下:

<template>
  {{ renderDataList }}
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";

const props = defineProps(["disableList", "type", "id"]);
const dataList = ref([]);

const renderDataList = computed(() => {
  // 根據(jù)disableList計(jì)算出list
  const newDataList = getListFromDisabledList(dataList.value);
  // 根據(jù)type計(jì)算出list
  return getListFromType(newDataList);
});

watch(
  () => props.id,
  () => {
    // 從服務(wù)端獲取dataList
    fetchDataList();
  },
  {
    immediate: true,
  }
);
</script>

我們?cè)?code>template中渲染的不再是dataList變量,而是renderDataList。renderDataList是一個(gè)computed,在這個(gè)computed中包含了所有dataList同步相關(guān)的邏輯。代碼邏輯流程圖是這樣的:

此時(shí)一位新同學(xué)接到產(chǎn)品需求要迭代dataList相關(guān)的業(yè)務(wù),因?yàn)槲覀兊恼麄€(gè)業(yè)務(wù)邏輯已經(jīng)變成了一條線(xiàn),新同學(xué)就可以很快的梳理清楚業(yè)務(wù)邏輯。再根據(jù)產(chǎn)品的需求看到底應(yīng)該是修改同步相關(guān)的邏輯還是異步相關(guān)的邏輯。下面這個(gè)是修改同步邏輯的demo:

const renderDataList = computed(() => {
  // 加上產(chǎn)品最新的業(yè)務(wù)邏輯
  const xxxList = getListFromXxx(dataList.value);
  // 根據(jù)disableList計(jì)算出list
  const newDataList = getListFromDisabledList(xxxList);
  // 根據(jù)type計(jì)算出list
  return getListFromType(newDataList);
});

總結(jié)

這篇文章介紹了watch主要分為兩種使用場(chǎng)景,一種是當(dāng)watch的值改變后需要同步更新渲染的dataList,另外一種是當(dāng)watch的值改變后需要異步從服務(wù)端獲取要渲染的dataList。如果不管同步還是異步都一股腦的將所有代碼都寫(xiě)在watch中,那么后續(xù)接手的維護(hù)者要梳理dataList相關(guān)的邏輯就會(huì)非常痛苦。因?yàn)榈教幎际?code>watch在更新dataList的值,完全不知道應(yīng)該在哪個(gè)watch中去加上最新的業(yè)務(wù)邏輯,這種時(shí)候我們一般就會(huì)再新加一個(gè)watch然后在新的watch中去實(shí)現(xiàn)最新的業(yè)務(wù)邏輯,時(shí)間久了代碼中就變成了一堆watch,維護(hù)性就變得越來(lái)越差。我們給出的優(yōu)化方案是將那些同步更新dataListwatch代碼全部摞到一個(gè)名為renderDataListcomputed,后續(xù)維護(hù)者只需要判斷新的業(yè)務(wù)如果是同步更新dataList,那么就將新的業(yè)務(wù)邏輯寫(xiě)在computed中。如果是要異步更新dataList,那么就將新的業(yè)務(wù)邏輯寫(xiě)在watch中。

到此這篇關(guān)于詳解Vue中如何避免濫用watch的文章就介紹到這了,更多相關(guān)Vue避免濫用watch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Vue中數(shù)據(jù)可視化詞云展示與詞云的生成

    詳解Vue中數(shù)據(jù)可視化詞云展示與詞云的生成

    數(shù)據(jù)可視化是現(xiàn)代Web應(yīng)用程序中的一個(gè)重要組成部分,詞云是一種非常流行的數(shù)據(jù)可視化形式,可以用來(lái)展示文本數(shù)據(jù)中的主題和關(guān)鍵字,本文我們將介紹如何在Vue中使用詞云庫(kù)進(jìn)行數(shù)據(jù)可視化詞云展示和詞云生成,需要的可以參考一下
    2023-06-06
  • VUE?項(xiàng)目如何使用?Docker+Nginx進(jìn)行打包部署

    VUE?項(xiàng)目如何使用?Docker+Nginx進(jìn)行打包部署

    使用?Docker,你可以創(chuàng)建一個(gè)包含?Vue.js?應(yīng)用程序的容器鏡像,并在任何支持?Docker?的環(huán)境中運(yùn)行該鏡像,這篇文章主要介紹了VUE?項(xiàng)目用?Docker+Nginx進(jìn)行打包部署,需要的朋友可以參考下
    2024-06-06
  • Vue網(wǎng)頁(yè)html轉(zhuǎn)換PDF(最低兼容ie10)的思路詳解

    Vue網(wǎng)頁(yè)html轉(zhuǎn)換PDF(最低兼容ie10)的思路詳解

    這篇文章主要介紹了Vue網(wǎng)頁(yè)html轉(zhuǎn)換PDF(最低兼容ie10)的思路詳解,實(shí)現(xiàn)此功能需要引入兩個(gè)插件,需要的朋友可以參考下
    2017-08-08
  • el-menu實(shí)現(xiàn)橫向溢出截取的示例代碼

    el-menu實(shí)現(xiàn)橫向溢出截取的示例代碼

    在進(jìn)行vue開(kāi)發(fā)的時(shí)候,我們不可避免會(huì)使用到導(dǎo)航菜單,element方便的為我們提供了導(dǎo)航菜單組件,下面這篇文章主要給大家介紹了關(guān)于el-menu實(shí)現(xiàn)橫向溢出截取的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 解決Mint-ui 框架Popup和Datetime Picker組件滾動(dòng)穿透的問(wèn)題

    解決Mint-ui 框架Popup和Datetime Picker組件滾動(dòng)穿透的問(wèn)題

    這篇文章主要介紹了解決Mint-ui 框架Popup和Datetime Picker組件滾動(dòng)穿透的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • vue實(shí)現(xiàn)各種文件文檔下載及導(dǎo)出示例

    vue實(shí)現(xiàn)各種文件文檔下載及導(dǎo)出示例

    這篇文章主要介紹了vue實(shí)現(xiàn)各種文件文檔下載及導(dǎo)出示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 基于Vue實(shí)現(xiàn)文件拖拽上傳功能

    基于Vue實(shí)現(xiàn)文件拖拽上傳功能

    文件拖拽上傳功能現(xiàn)在已經(jīng)隨處可見(jiàn),大家應(yīng)該都用過(guò)了吧,那么它具體是怎么實(shí)現(xiàn)的大家有去了解過(guò)嗎,今天我們一起來(lái)實(shí)現(xiàn)一下這個(gè)功能,并封裝一個(gè)拖拽上傳組件吧
    2024-03-03
  • Vue中添加手機(jī)驗(yàn)證碼組件功能操作方法

    Vue中添加手機(jī)驗(yàn)證碼組件功能操作方法

    組件是Vue.js最強(qiáng)大的功能之一。組件可以擴(kuò)展HTML元素,封裝可重用的代碼。這篇文章主要介紹了VUE 中添加手機(jī)驗(yàn)證碼組件,需要的朋友可以參考下
    2017-12-12
  • vue按需加載實(shí)例詳解

    vue按需加載實(shí)例詳解

    在本篇文章里小編給大家整理的是關(guān)于vue按需加載實(shí)例的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以學(xué)習(xí)參考下。
    2019-09-09
  • Vue使用axios進(jìn)行數(shù)據(jù)異步交互的方法

    Vue使用axios進(jìn)行數(shù)據(jù)異步交互的方法

    大家都知道在Vue里面有兩種出名的插件能夠支持發(fā)起異步數(shù)據(jù)傳輸和接口交互,分別是axios和vue-resource,同時(shí)vue更新到2.0之后,宣告不再對(duì)vue-resource更新,而是推薦的axios,今天就講一下怎么引入axios,需要的朋友可以參考下
    2024-01-01

最新評(píng)論