首頁 > web前端 > js教程 > 您需要了解的 Vue 可組合技巧

您需要了解的 Vue 可組合技巧

Susan Sarandon
發布: 2025-01-11 08:46:44
原創
624 人瀏覽過

Vue Composables Tips You Need to Know

Vue 可組合項非常強大,但如果您不小心,它們很快就會變得混亂且難以維護。

這就是為什麼我確定了 13 個技巧,可以幫助您編寫更好、更易於維護的可組合項。

無論您是建立簡單的狀態管理解決方案還是複雜的共享邏輯,這些技巧都將為您提供幫助:

  • 避免導致義大利麵式程式碼的常見陷阱
  • 編寫更易於測試和維護的可組合項
  • 建立更靈活、可重複使用的共享邏輯
  • 如果需要,請逐漸從 Options API 移轉到 Composition API

您將學到的技巧是:

  1. 避免透過多個組件進行 Prop 鑽孔
  2. 在不相關的組件之間共享資料
  3. 用清晰的方法控制狀態更新
  4. 將大組件分解為較小的函數
  5. 將業務邏輯與 Vue 反應性分開
  6. 在一個函數中處理同步和非同步資料
  7. 使函數參數更具描述性
  8. 防止使用預設值的未定義選項
  9. 根據需要傳回簡單或複雜的值
  10. 將不同的邏輯路徑分成各自的函數
  11. 一致地處理反應值和原始值
  12. 簡化引用展開
  13. 逐步從Options API遷移到Composition API

讓我們深入研究每種模式,看看它們如何改進您的 Vue 應用程式。

別忘了,在下面留言你最喜歡的提示!

1. 避免透過多個組件進行支柱鑽孔

資料儲存模式可以幫助避免透過多個元件層傳遞道具和事件。

一種情況是父母和孩子透過無休止的道具鑽探和事件冒泡進行交流:

<!-- Parent.vue -->
<template>
  <!-- But many more layers of components -->
  <Child :user="user" @change="onUserChange" />
</template>

<script setup>
const user = ref({ name: 'Alice' })
function onUserChange(updatedUser) {
  user.value = updatedUser
}
</script>
登入後複製
登入後複製
登入後複製

這會造成很大的複雜性,因為這些道具和事件必須在元件層次結構中來回移動。

更簡單的解決方案是建立一個任何元件都可以匯入的共享資料儲存:

import { reactive, toRefs } from 'vue'
const state = reactive({ user: { name: 'Alice' } })

export function useUserStore() {
  return toRefs(state)
}
登入後複製
登入後複製
登入後複製

2. 在不相關的組件之間共享數據

當兄弟或「表兄弟」組件需要在沒有任何直接連接的情況下共享相同的資料時,資料儲存模式也會有所幫助。

假設兩個兄弟姊妹都需要相同的使用者對象,但沒有優雅的道具或事件路徑。

這通常會導致在父狀態或重複狀態之間進行尷尬的資料處理。

更好的方法是依賴一個兄弟姊妹都可以使用的可組合儲存:

// SiblingA.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()

// SiblingB.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()
登入後複製
登入後複製
登入後複製

3. 使用清晰的方法控制狀態更新

資料儲存模式鼓勵提供清晰的方法來更新共享狀態。

有些開發人員將整個反應式物件暴露給世界,如下所示:

<!-- Parent.vue -->
<template>
  <!-- But many more layers of components -->
  <Child :user="user" @change="onUserChange" />
</template>

<script setup>
const user = ref({ name: 'Alice' })
function onUserChange(updatedUser) {
  user.value = updatedUser
}
</script>
登入後複製
登入後複製
登入後複製

這使得任何人都可以直接從任何檔案更改使用者的 darkMode 屬性,這可能會導致分散的、不受控制的突變。

更好的想法是將狀態傳回為唯讀以及定義更新如何發生的函數:

import { reactive, toRefs } from 'vue'
const state = reactive({ user: { name: 'Alice' } })

export function useUserStore() {
  return toRefs(state)
}
登入後複製
登入後複製
登入後複製

4. 將大型組件分解為較小的功能

內聯可組合模式透過將相關狀態和邏輯收集到較小的函數中來幫助分解大型組件。

一個巨大的組件可能會將其所有引用和方法放在一個地方:

// SiblingA.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()

// SiblingB.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()
登入後複製
登入後複製
登入後複製

這種設定很快就會變得難以管理。

相反,內聯可組合項可以將邏輯分組並在本地提供。然後我們可以稍後將其提取到一個單獨的文件中:

export const user = reactive({ darkMode: false })
登入後複製
登入後複製

5. 將業務邏輯與 Vue 反應性分開

精簡可組合模式告訴我們將原始業務邏輯與 Vue 反應性分開,以便測試和維護變得更簡單。

您可以將所有邏輯嵌入可組合項目中:

import { reactive, readonly } from 'vue'
const state = reactive({ darkMode: false })

export function toggleDarkMode() {
  state.darkMode = !state.darkMode
}

export function useUserStore() {
  return {
    darkMode: readonly(state.darkMode),
    toggleDarkMode
  }
}
登入後複製
登入後複製

這迫使您在 Vue 環境中測試邏輯。

相反,將複雜的規則保留在純函數中,並讓可組合項僅處理反應式包裝器:

<script setup>
const count = ref(0)
const user = ref({ name: 'Alice' })
// 500 more lines of intertwined code with watchers, methods, etc.
</script>
登入後複製
登入後複製

6. 在一個函數中處理同步和非同步數據

非同步同步可組合模式將同步和非同步步行為合併到一個可組合中,而不是建立單獨的函數。

這就像 Nuxt 的 useAsyncData 的工作原理一樣。

這裡我們有一個可組合項,它可以回傳承諾,同時也為同步使用提供即時反應屬性:

<script setup>
function useCounter() {
  const count = ref(0)
  const increment = () => count.value++
  return { count, increment }
}

const { count, increment } = useCounter()
</script>
登入後複製
登入後複製

7. 讓函數參數更具描述性

選項物件模式可以透過期望單一配置物件來清除長參數清單。

這樣的呼叫比較麻煩而且容易出錯,新增選項需要更新函數簽章:

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = (count.value * 3) / 2
  }
  return { count, increment }
}
登入後複製
登入後複製

每個參數代表什麼並不明顯。

接受選項物件的可組合項使所有內容保持描述性:

// counterLogic.js
export function incrementCount(num) {
  return (num * 3) / 2
}

// useCounter.js
import { ref } from 'vue'
import { incrementCount } from './counterLogic'

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = incrementCount(count.value)
  }
  return { count, increment }
}
登入後複製
登入後複製

8. 防止使用預設值的未定義選項

選項物件模式也建議每個屬性的預設值。

假設某些欄位存在的函數如果未傳遞,可能會出現問題:

import { ref } from 'vue'

export function useAsyncOrSync() {
  const data = ref(null)
  const promise = fetch('/api')
    .then(res => res.json())
    .then(json => {
      data.value = json
      return { data }
    })
  return Object.assign(promise, { data })
}
登入後複製
登入後複製

最好使用安全預設值解構選項:

useRefHistory(someRef, true, 10, 500, 'click', false)
登入後複製

9. 根據需要傳回簡單或複雜的值

動態回傳模式可確保可組合項目可以傳回簡單用例的單一值或具有更高階控制項的擴充物件。

有些方法總是傳回一個包含所有內容的物件:

<!-- Parent.vue -->
<template>
  <!-- But many more layers of components -->
  <Child :user="user" @change="onUserChange" />
</template>

<script setup>
const user = ref({ name: 'Alice' })
function onUserChange(updatedUser) {
  user.value = updatedUser
}
</script>
登入後複製
登入後複製
登入後複製

任何只需要主要無功值的人都被迫處理額外的東西。

有條件回傳單一引用或物件的可組合項解決了:

import { reactive, toRefs } from 'vue'
const state = reactive({ user: { name: 'Alice' } })

export function useUserStore() {
  return toRefs(state)
}
登入後複製
登入後複製
登入後複製

10.將不同的邏輯路徑分成各自的功能

隱藏可組合項模式有助於避免在相同可組合項中混合互斥邏輯。

有些程式碼將多種模式或程式碼路徑組合在一起:

// SiblingA.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()

// SiblingB.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()
登入後複製
登入後複製
登入後複製

將每個路徑拆分為自己的可組合項更加清晰,並且不會影響功能:

export const user = reactive({ darkMode: false })
登入後複製
登入後複製

11. 一致地處理反應值和原始值

靈活參數模式確保可組合項中的輸入和輸出被統一處理為反應資料或原始值,避免混淆。

有些程式碼檢查輸入是否為引用:

import { reactive, readonly } from 'vue'
const state = reactive({ darkMode: false })

export function toggleDarkMode() {
  state.darkMode = !state.darkMode
}

export function useUserStore() {
  return {
    darkMode: readonly(state.darkMode),
    toggleDarkMode
  }
}
登入後複製
登入後複製

相反,您可以立即轉換。

透過使用 ref,如果輸入是 ref,則會傳回該 ref。否則,它將被轉換為 ref:

<script setup>
const count = ref(0)
const user = ref({ name: 'Alice' })
// 500 more lines of intertwined code with watchers, methods, etc.
</script>
登入後複製
登入後複製

12. 簡化引用展開

當需要展開時,靈活參數模式也會使用 toValue。

沒有它,程式碼可能會繼續執行 isRef 檢查:

<script setup>
function useCounter() {
  const count = ref(0)
  const increment = () => count.value++
  return { count, increment }
}

const { count, increment } = useCounter()
</script>
登入後複製
登入後複製

呼叫更簡單:

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = (count.value * 3) / 2
  }
  return { count, increment }
}
登入後複製
登入後複製

13. 逐步從Options API遷移到Composition API

Options to Composition 模式可讓您以易於遵循的增量方式逐步將大型 Options API 元件遷移到 Composition API。

經典的選項組件可能會這樣做:

// counterLogic.js
export function incrementCount(num) {
  return (num * 3) / 2
}

// useCounter.js
import { ref } from 'vue'
import { incrementCount } from './counterLogic'

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = incrementCount(count.value)
  }
  return { count, increment }
}
登入後複製
登入後複製

資料、計算屬性和方法是分散的。

將其轉換為腳本設定將它們組合在一起,使其更易於遵循,並允許您使用這些模式:

import { ref } from 'vue'

export function useAsyncOrSync() {
  const data = ref(null)
  const promise = fetch('/api')
    .then(res => res.json())
    .then(json => {
      data.value = json
      return { data }
    })
  return Object.assign(promise, { data })
}
登入後複製
登入後複製

把它包起來

這 13 個技巧將幫助您編寫更好的 Vue 可組合項,更容易在應用程式中維護、測試和重複使用。

但我們只是觸及了表面。

多年來,我收集了更多模式和技巧,並將它們全部放入可組合模式的深入課程中。

總共涵蓋16種圖案,每種圖案有:

  • 深入解釋 — 何時使用它、邊緣情況和變體
  • 現實世界的範例 - 這樣您就可以了解如何使用這些簡單範例以外的它們
  • 逐步重建範例 — 這樣您就可以了解如何將它們應用到您自己的程式碼中

到這裡了解更多。

哦,這門課程優惠至 1 月 15 日,所以您現在就可以享受超值折扣!

查看可組合設計模式

以上是您需要了解的 Vue 可組合技巧的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板