狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

常見的 Vue.js 開發(fā)錯(cuò)誤

admin
2024年11月27日 19:54 本文熱度 928

簡介

Vue.js 為開發(fā)人員提供了豐富的功能,既能加快開發(fā)速度,又能構(gòu)建健壯且高性能的應(yīng)用程序。

盡管這些功能有其優(yōu)勢,但如果使用不當(dāng),也可能成為錯(cuò)誤的根源,導(dǎo)致開發(fā)人員花費(fèi)大量時(shí)間進(jìn)行調(diào)試。錯(cuò)誤不僅影響開發(fā)效率,還可能導(dǎo)致應(yīng)用程序性能下降,最終影響 Vue 應(yīng)用的整體表現(xiàn)。

我們可以從他人的錯(cuò)誤中汲取教訓(xùn),在保證應(yīng)用程序功能和性能的同時(shí),編寫更加簡潔的代碼。


本文中,我使用 Vite 創(chuàng)建了一個(gè)最小化的 Vue 應(yīng)用程序。你可以從這個(gè)倉庫克隆該項(xiàng)目。在本地安裝依賴后,運(yùn)行 pnpm i 安裝依賴,并啟動(dòng)開發(fā)服務(wù)器。


場景 1:在 v-for 循環(huán)中使用非唯一的 ID

該錯(cuò)誤通常在以下兩種情況中出現(xiàn):

  1. 對數(shù)組中的元素進(jìn)行排序。
  2. 循環(huán)中的組件具有內(nèi)部狀態(tài)。

為便于演示,以下是一個(gè)代碼片段:

async function fetchData({
  try {
    const dataFromApi = await axios.get(
      "https://dummyjson.com/recipes?page=1&limit=10&skip=10&select=name,image"
    );
    const recipes = dataFromApi.data.recipes as Recipe[];

    favoriteRecipeList.value = [...favoriteRecipeList.value, ...recipes];
    isLoading.value = false;
  } catch (e) {
    isLoading.value = false;
    console.log(e);
  }
}

該函數(shù)從源數(shù)據(jù)獲取信息,并填充到本地變量中,然后使用 v-for 循環(huán)渲染配方列表,同時(shí)考慮到 SingleRecipe 組件有自己的內(nèi)部狀態(tài)。


<template>
  <main class="md:min-h-screen md:p-5 p-2">
    <h1 class="text-5xl">Ouch, Mistakes.</h1>

    <section
      v-if="isLoading"
      class="w-full h-72 flex flex-col items-center justify-center"
    >

      <p class="text-3xl">Loading...</p>
    </section>

    <section
      v-auto-animate
      v-else
      class="w-full grid md:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-3 mt-16 relative mb-14"
    >

      <button
        :disabled="!haveRecipes"
        @click="shuffleRecipe"
        class="px-4 py-1.5 absolute -top-16 right-5 bg-green-700 text-white"
      >

        Shuffle
      </button>
      <SingleRecipe
        v-for="(item, index) in favoriteRecipeList"
        :key="index"
        :recipe="item"
      />

    </section>
  </main>
</template>

以下是該示例的結(jié)果:

由于我們將數(shù)組的索引作為循環(huán)的 key,一切看起來正常。當(dāng)我們點(diǎn)擊“洗牌”按鈕時(shí),雖然配方的順序發(fā)生了變化,但預(yù)期的過渡效果卻沒有顯示。

原因在于,每當(dāng) key 值變化時(shí),「Vue 會(huì)使用這些 key 來強(qiáng)制重新渲染」。然而,由于我們使用的是數(shù)組索引作為 key,即使列表發(fā)生變化,索引也不會(huì)改變,因此 Vue 沒有重新渲染元素,過渡效果也就沒有觸發(fā)。

為了解決這個(gè)問題,我們可以使用一個(gè)更具唯一性的值作為 key,幫助 Vue 跟蹤列表中元素的變化:

 <SingleRecipe
   v-for="item in favoriteRecipeList"
   :key="item.name"
   :recipe="item"
 />

如圖所示,過渡效果現(xiàn)在已按預(yù)期正常工作。

場景 2:依賴非響應(yīng)式值

在使用瀏覽器 API(如本地存儲(chǔ)和地理位置)時(shí),開發(fā)人員往往需要響應(yīng)式的功能。但傳統(tǒng)的瀏覽器 API 本身并不具備響應(yīng)式,因此開發(fā)人員可能會(huì)誤用它們作為計(jì)算屬性的值。

以下是一個(gè)代碼示例,演示如何使用 ref 訪問視頻元素的屬性。

<script setup lang="ts">
import { ref, computed } from "vue";
import PlayButton from "@/components/icons/PlayButton.vue";
import PauseButton from "@/components/icons/PauseButton.vue";

const videoPlayer = ref<HTMLVideoElement>();
const playing = computed(() => !videoPlayer.value?.paused);

</script>

我們使用計(jì)算屬性來跟蹤視頻的播放狀態(tài),并在模板中顯示對應(yīng)的播放/暫停狀態(tài)。

<template>
  <main class="md:min-h-screen md:p-5 p-2">
    <h1 class="text-5xl">Ouch, Mistakes. - Non reactive dependency.</h1>

    <section class="mt-16 relative">
      <video src="/shrek_meets_donkey.mp4" ref="videoPlayer" class="mx-auto h-96" />
      <div
        v-auto-animate
        class="inline-flex gap-3 absolute top-[48%] right-[46%]"
      >

        <button
          @click="videoPlayer?.play()"
          v-if="playing"
          class="p-2 rounded-md bg-black"
        >

          <PlayButton />
        </button>
        <button
          v-else
          @click="videoPlayer?.pause()"
          class="p-2 rounded-md bg-red-700"
        >

          <PauseButton />
        </button>
      </div>
    </section>
  </main>
</template>

然而,在這種情況下,控制按鈕的狀態(tài)并不是響應(yīng)式的:

這是因?yàn)橛?jì)算屬性依賴了一個(gè)非響應(yīng)式的值。

為了解決這個(gè)問題,我們可以使用 Vueuse 庫。這個(gè)庫提供了一系列組合式 API,使瀏覽器 API 具備響應(yīng)式特性,避免了重復(fù)造輪子的麻煩。

例如,我們可以使用 useMediaControls 這個(gè)組合式 API,輕松為媒體控制添加響應(yīng)式支持:

<template>
  <main class="md:min-h-screen md:p-5 p-2">
    <h1 class="text-5xl">Ouch, Mistakes. - Non reactive dependency.</h1>

    <section class="mt-16 relative">
      <video ref="videoRef" class="mx-auto h-96" />
      <div
        v-auto-animate
        class="inline-flex gap-3 absolute top-[48%] right-[46%]"
      >

        <button
          @click="videoRef?.play()"
          v-if="!videoPlaying"
          class="p-2 rounded-md bg-black"
        >

          <PlayButton />
        </button>
        <button
          v-else
          @click="videoRef?.pause()"
          class="p-2 rounded-md bg-red-700"
        >

          <PauseButton />
        </button>
      </div>
    </section>
  </main>
</template>
<script setup lang="ts">
import { ref, computed } from "vue";
import { useMediaControls } from "@vueuse/core";
import PlayButton from "@/components/icons/PlayButton.vue";
import PauseButton from "@/components/icons/PauseButton.vue";

const videoRef = ref();
const { playing: videoPlaying} = useMediaControls(videoRef, {
  src"/shrek_meets_donkey.mp4",
});
</script>

如預(yù)期一樣,它正常工作,因?yàn)?nbsp;useMediaControls 提供了一個(gè)響應(yīng)式的 ref,可以在模板中用于顯示視頻的播放狀態(tài)。

此外,useMediaControls 還提供了其他有用的屬性,以便開發(fā)者對媒體進(jìn)行更多控制。

場景 3:替換響應(yīng)式值

使用 Vue 的響應(yīng)式 API 時(shí),需要特別小心,避免錯(cuò)誤地替換整個(gè)對象,從而失去響應(yīng)性。

以下是一個(gè)代碼示例,

<template>
  <main class="md:min-h-screen md:p-5 p-2">
    <h1 class="text-5xl">Ouch, Mistakes - Replacing reactive value</h1>

    <section class="mt-16 relative">
      <button
        @click="loadMoreBirds"
        class="px-4 py-1.5 absolute -top-16 right-5 bg-green-700 text-white"
      >

        Add more bird
      </button>
      <h1 class="text-3xl my-3">Swift birds in Europe</h1>
      <pre>{{ arrLength }}</pre>

      <h1 class="text-3xl my-3" v-if="isLoading">Loading...</h1>
      <ul v-else class="list-disc pl-3">
        <li v-for="item in swiftBirdsInEurope" :key="item">{{ item }}</li>
      </ul>
    </section>
  </main>
</template>

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

const isLoading = ref(false);

let swiftBirdsInEurope = reactive([
  "Alpine swift",
  "Chimney swift",
  "Pacific swift",
]);

const arrLength = computed(() => swiftBirdsInEurope.length)

function loadMoreBirds({
  isLoading.value = true;
  swiftBirdsInEurope = [
    "Common swift",
    "Little swift",
    "Pallid swift",
    "White-rumped swift",
  ];
  setTimeout(() => (isLoading.value = false), 2000);
}
</script>

在 loadMoreBirds 函數(shù)中更新響應(yīng)式值為一個(gè)新的鳥類列表。使用 Vue 開發(fā)工具檢查時(shí),雖然值確實(shí)更新了,但計(jì)算屬性似乎沒有重新計(jì)算。

出現(xiàn)這個(gè)問題的原因是我們在用新數(shù)組替換響應(yīng)式值時(shí),斷開了與響應(yīng)式系統(tǒng)的連接。

這是 Vue 響應(yīng)式 API 的已知限制。響應(yīng)式 API 無法追蹤已替換的對象,導(dǎo)致視圖未更新。

為了解決這個(gè)問題,我們建議使用 ref 來存儲(chǔ)數(shù)據(jù)。ref 允許數(shù)據(jù)的可變性,同時(shí)保留響應(yīng)性。它還能正確存儲(chǔ)原始值,這是它的一個(gè)優(yōu)勢。

總結(jié)

不當(dāng)使用 Vue API 可能會(huì)導(dǎo)致意想不到的錯(cuò)誤。開發(fā)人員需要在特定情況下遵循適當(dāng)?shù)?API 使用規(guī)范,確保代碼的響應(yīng)性和應(yīng)用的性能。


原文地址:https://medium.com/@dimeji.ogunleye20/common-vuejs-development-mistakes-10877bdc591d


該文章在 2024/11/28 17:41:21 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved