最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3?邏輯復(fù)用的實(shí)現(xiàn)示例

 更新時(shí)間:2024年02月04日 08:36:22   作者:王大可996  
在項(xiàng)目開發(fā)中,有兩個(gè)功能特別類似,如果單獨(dú)實(shí)現(xiàn),會(huì)有很多重復(fù)的代碼,這時(shí)候就會(huì)用到邏輯復(fù)用,本文主要介紹了vue3?邏輯復(fù)用的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下

什么是組合式函數(shù)

_無(wú)狀態(tài)邏輯的函數(shù)_:它在接收一些輸入后立刻返回所期望的輸出。

比如 時(shí)間格式化的函數(shù)。

有狀態(tài)邏輯的函數(shù): 有狀態(tài)邏輯負(fù)責(zé)管理會(huì)隨時(shí)間而變化的狀態(tài)。

比如 跟蹤當(dāng)前鼠標(biāo)在頁(yè)面中的位置。

在 Vue 應(yīng)用的概念中,“組合式函數(shù)”(Composables) 是一個(gè)利用 Vue 的組合式 API 來(lái)封裝和復(fù)用有狀態(tài)邏輯的函數(shù)。

一個(gè)簡(jiǎn)單的例子是跟蹤當(dāng)前鼠標(biāo)在頁(yè)面中的位置。在實(shí)際應(yīng)用中,也可能是像觸摸手勢(shì)或與數(shù)據(jù)庫(kù)的連接狀態(tài)這樣的更復(fù)雜的邏輯。

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

const x = ref(0);
const y = ref(0);

function update(event: any) {
  x.value = event.pageX;
  y.value = event.pageY;
}

onMounted(() => window.addEventListener("mousemove", update));
onUnmounted(() => window.removeEventListener("mousemove", update));
</script>

<template>
  <div class="container">鼠標(biāo)坐標(biāo)是: {{ x }}, {{ y }}</div>
</template>

組合函數(shù)提取,進(jìn)行邏輯復(fù)用封裝

// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'

// 按照慣例,組合式函數(shù)名以“use”開頭
export function useMouse() {
  // 被組合式函數(shù)封裝和管理的狀態(tài)
  const x = ref(0)
  const y = ref(0)

  // 組合式函數(shù)可以隨時(shí)更改其狀態(tài)。
  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  // 一個(gè)組合式函數(shù)也可以掛靠在所屬組件的生命周期上
  // 來(lái)啟動(dòng)和卸載副作用
  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  // 通過(guò)返回值暴露所管理的狀態(tài)
  return { x, y }
}

封裝后的使用方式:

<script lang="ts" setup>
import { useMouse } from "@/components/common/mouse.js";
const { x, y } = useMouse();
</script>

<template>
  <div class="container">鼠標(biāo)坐標(biāo)是: {{ x }}, {{ y }}</div>
</template>

可以在組合式函數(shù)中使用所有的組合式 API。

組合式函數(shù)還可以嵌套多個(gè)組合式函數(shù)。

我們可以將添加和清除 DOM 事件監(jiān)聽器的邏輯也封裝進(jìn)一個(gè)組合式函數(shù)中

// event.js
import { onMounted, onUnmounted } from 'vue'

export function useEventListener(target, event, callback) {
  // 如果你想的話,
  // 也可以用字符串形式的 CSS 選擇器來(lái)尋找目標(biāo) DOM 元素
  onMounted(() => target.addEventListener(event, callback))
  onUnmounted(() => target.removeEventListener(event, callback))
}

有了它,之前的 useMouse() 組合式函數(shù)可以被簡(jiǎn)化為:

// mouse.js
import { ref } from 'vue'
import { useEventListener } from './event'

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  useEventListener(window, 'mousemove', (event) => {
    x.value = event.pageX
    y.value = event.pageY
  })

  return { x, y }
}

每一個(gè)調(diào)用 useMouse() 的組件實(shí)例會(huì)創(chuàng)建其獨(dú)有的 x、y 狀態(tài)拷貝,因此他們不會(huì)互相影響。

如果你想要在組件之間共享狀態(tài),后面回學(xué)到狀態(tài)管理。

###異步狀態(tài)示例

需要接收一個(gè)參數(shù)的組合式函數(shù)示例。在做異步數(shù)據(jù)請(qǐng)求時(shí),我們常常需要處理不同的狀態(tài):加載中、加載成功和加載失敗。

// fetch.js
import { ref, watchEffect, toValue } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)

  const fetchData = () => {
    // reset state before fetching..
    data.value = null
    error.value = null

    fetch(toValue(url))
      .then((res) => res.json())
      .then((json) => (data.value = json))
      .catch((err) => (error.value = err))
  }

  watchEffect(() => {
    fetchData()
  })

  return { data, error }
}

toValue() 是一個(gè)在 3.3 版本中新增的 API。它的設(shè)計(jì)目的是將 ref 或 getter 規(guī)范化為值。如果參數(shù)是 ref,它會(huì)返回 ref 的值;如果參數(shù)是函數(shù),它會(huì)調(diào)用函數(shù)并返回其返回值。否則,它會(huì)原樣返回參數(shù)。它的工作方式類似于 unref(),但對(duì)函數(shù)有特殊處理。

注意 toValue(url) 是在 watchEffect 回調(diào)函數(shù)的內(nèi)部調(diào)用的。這確保了在 toValue() 規(guī)范化期間訪問(wèn)的任何響應(yīng)式依賴項(xiàng)都會(huì)被偵聽器跟蹤。

這個(gè)版本的 useFetch() 現(xiàn)在能接收靜態(tài) URL 字符串、ref 和 getter,使其更加靈活。watch effect 會(huì)立即運(yùn)行,并且會(huì)跟蹤 toValue(url) 期間訪問(wèn)的任何依賴項(xiàng)。如果沒(méi)有跟蹤到依賴項(xiàng)(例如 url 已經(jīng)是字符串),則 effect 只會(huì)運(yùn)行一次;否則,它將在跟蹤到的任何依賴項(xiàng)更改時(shí)重新運(yùn)行。

約定和最佳實(shí)踐

命名

組合式函數(shù)約定用駝峰命名法命名,并以“use”作為開頭。

輸入?yún)?shù)

即便不依賴于 ref 或 getter 的響應(yīng)性,組合式函數(shù)也可以接收它們作為參數(shù)。如果你正在編寫一個(gè)可能被其他開發(fā)者使用的組合式函數(shù),最好處理一下輸入?yún)?shù)是 ref 或 getter 而非原始值的情況。可以利用 toValue() 工具函數(shù)來(lái)實(shí)現(xiàn):

import { toValue } from 'vue'

function useFeature(maybeRefOrGetter) {
  // 如果 maybeRefOrGetter 是一個(gè) ref 或 getter,
  // 將返回它的規(guī)范化值。
  // 否則原樣返回。
  const value = toValue(maybeRefOrGetter)
}

如果你的組合式函數(shù)在輸入?yún)?shù)是 ref 或 getter 的情況下創(chuàng)建了響應(yīng)式 effect,為了讓它能夠被正確追蹤,請(qǐng)確保要么使用 watch() 顯式地監(jiān)視 ref 或 getter,要么在 watchEffect() 中調(diào)用 toValue()。

返回值

你可能已經(jīng)注意到了,我們一直在組合式函數(shù)中使用 ref() 而不是 reactive()。我們推薦的約定是組合式函數(shù)始終返回一個(gè)包含多個(gè) ref 的普通的非響應(yīng)式對(duì)象,這樣該對(duì)象在組件中被解構(gòu)為 ref 之后仍可以保持響應(yīng)性:

// x 和 y 是兩個(gè) ref
const { x, y } = useMouse()

從組合式函數(shù)返回一個(gè)響應(yīng)式對(duì)象會(huì)導(dǎo)致在對(duì)象解構(gòu)過(guò)程中丟失與組合式函數(shù)內(nèi)狀態(tài)的響應(yīng)性連接。與之相反,ref 則可以維持這一響應(yīng)性連接。

如果你更希望以對(duì)象屬性的形式來(lái)使用組合式函數(shù)中返回的狀態(tài),你可以將返回的對(duì)象用 reactive() 包裝一次,這樣其中的 ref 會(huì)被自動(dòng)解包,例如:

const mouse = reactive(useMouse())
// mouse.x 鏈接到了原來(lái)的 x ref
console.log(mouse.x)

使用限制

組合式函數(shù)只能在 <script setup> 或 setup() 鉤子中被調(diào)用。在這些上下文中,它們也只能被同步調(diào)用。在某些情況下,你也可以在像 onMounted() 這樣的生命周期鉤子中調(diào)用它們。

這些限制很重要,因?yàn)檫@些是 Vue 用于確定當(dāng)前活躍的組件實(shí)例的上下文。訪問(wèn)活躍的組件實(shí)例很有必要,這樣才能:

  • 將生命周期鉤子注冊(cè)到該組件實(shí)例上

  • 將計(jì)算屬性和監(jiān)聽器注冊(cè)到該組件實(shí)例上,以便在該組件被卸載時(shí)停止監(jiān)聽,避免內(nèi)存泄漏。

<script setup> 是唯一在調(diào)用 await 之后仍可調(diào)用組合式函數(shù)的地方。編譯器會(huì)在異步操作之后自動(dòng)為你恢復(fù)當(dāng)前的組件實(shí)例。

與其他模式的比較

和 Mixin 的對(duì)比

Vue 2 的用戶可能會(huì)對(duì) mixins 選項(xiàng)比較熟悉。它也讓我們能夠把組件邏輯提取到可復(fù)用的單元里。然而 mixins 有三個(gè)主要的短板:

不清晰的數(shù)據(jù)來(lái)源:當(dāng)使用了多個(gè) mixin 時(shí),實(shí)例上的數(shù)據(jù)屬性來(lái)自哪個(gè) mixin 變得不清晰,這使追溯實(shí)現(xiàn)和理解組件行為變得困難。這也是我們推薦在組合式函數(shù)中使用 ref + 解構(gòu)模式的理由:讓屬性的來(lái)源在消費(fèi)組件時(shí)一目了然。

命名空間沖突:多個(gè)來(lái)自不同作者的 mixin 可能會(huì)注冊(cè)相同的屬性名,造成命名沖突。若使用組合式函數(shù),你可以通過(guò)在解構(gòu)變量時(shí)對(duì)變量進(jìn)行重命名來(lái)避免相同的鍵名。

隱式的跨 mixin 交流:多個(gè) mixin 需要依賴共享的屬性名來(lái)進(jìn)行相互作用,這使得它們隱性地耦合在一起。而一個(gè)組合式函數(shù)的返回值可以作為另一個(gè)組合式函數(shù)的參數(shù)被傳入,像普通函數(shù)那樣。

基于上述理由,我們不再推薦在 Vue 3 中繼續(xù)使用 mixin。保留該功能只是為了項(xiàng)目遷移的需求和照顧熟悉它的用戶。

和無(wú)渲染組件的對(duì)比

在組件插槽一章中,我們討論過(guò)了基于作用域插槽的無(wú)渲染組件。我們甚至用它實(shí)現(xiàn)了一樣的鼠標(biāo)追蹤器示例。

組合式函數(shù)相對(duì)于無(wú)渲染組件的主要優(yōu)勢(shì)是:組合式函數(shù)不會(huì)產(chǎn)生額外的組件實(shí)例開銷。當(dāng)在整個(gè)應(yīng)用中使用時(shí),由無(wú)渲染組件產(chǎn)生的額外組件實(shí)例會(huì)帶來(lái)無(wú)法忽視的性能開銷。

我們推薦在純邏輯復(fù)用時(shí)使用組合式函數(shù),在需要同時(shí)復(fù)用邏輯和視圖布局時(shí)使用無(wú)渲染組件。

和 React Hooks 的對(duì)比

如果你有 React 的開發(fā)經(jīng)驗(yàn),你可能注意到組合式函數(shù)和自定義 React hooks 非常相似。組合式 API 的一部分靈感正來(lái)自于 React hooks,Vue 的組合式函數(shù)也的確在邏輯組合能力上與 React hooks 相近。然而,Vue 的組合式函數(shù)是基于 Vue 細(xì)粒度的響應(yīng)性系統(tǒng),這和 React hooks 的執(zhí)行模型有本質(zhì)上的不同。這一話題在組合式 API 的常見問(wèn)題中有更細(xì)致的討論。

到此這篇關(guān)于vue3 邏輯復(fù)用的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)vue3 邏輯復(fù)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue-cli創(chuàng)建項(xiàng)目及項(xiàng)目結(jié)構(gòu)解析

    vue-cli創(chuàng)建項(xiàng)目及項(xiàng)目結(jié)構(gòu)解析

    上一篇我們安裝了vue-cli,接下來(lái)我們就使用該腳手架進(jìn)行創(chuàng)建項(xiàng)目,這篇文章主要介紹了vue-cli創(chuàng)建項(xiàng)目以及項(xiàng)目結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-10-10
  • vite+vue3項(xiàng)目中svg圖標(biāo)組件封裝的過(guò)程詳解

    vite+vue3項(xiàng)目中svg圖標(biāo)組件封裝的過(guò)程詳解

    這篇文章主要介紹了vite+vue3項(xiàng)目中svg圖標(biāo)組件封裝的過(guò)程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • Vue組件通信方法案例總結(jié)

    Vue組件通信方法案例總結(jié)

    這篇文章主要介紹了Vue組件通信方法案例總結(jié),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • vue集成高德地圖amap-jsapi-loader的實(shí)現(xiàn)

    vue集成高德地圖amap-jsapi-loader的實(shí)現(xiàn)

    本文主要介紹了vue集成高德地圖amap-jsapi-loader的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • vue element-ui表格自定義動(dòng)態(tài)列具體實(shí)現(xiàn)

    vue element-ui表格自定義動(dòng)態(tài)列具體實(shí)現(xiàn)

    這周工作中遇見了一個(gè)表格動(dòng)態(tài)列的需求,下面這篇文章主要給大家介紹了關(guān)于vue element-ui表格自定義動(dòng)態(tài)列具體實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Vue3中Cesium地圖初始化及地圖控件配置方法

    Vue3中Cesium地圖初始化及地圖控件配置方法

    本文中,我們主要介紹Cesium在Vue3運(yùn)行環(huán)境的配置,及Cesium實(shí)例中控件的顯隱設(shè)置,本項(xiàng)目基于pnpm安裝,也可使用其他包管理器進(jìn)行安裝,如npm或yarn,本文通過(guò)示例代碼對(duì)vue初始化Cesium地圖相關(guān)知識(shí)介紹的非常詳細(xì),需要的朋友參考下吧
    2023-07-07
  • vue填坑之webpack run build 靜態(tài)資源找不到的解決方法

    vue填坑之webpack run build 靜態(tài)資源找不到的解決方法

    今天小編就為大家分享一篇vue填坑之webpack run build 靜態(tài)資源找不到的解決方法。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • vue-router路由懶加載及實(shí)現(xiàn)方式

    vue-router路由懶加載及實(shí)現(xiàn)方式

    這篇文章主要介紹了vue-router路由懶加載及實(shí)現(xiàn)方式,路由懶加載的主要作用是將 路由對(duì)應(yīng)的組件打包成一個(gè)個(gè)的js代碼塊,只有在這個(gè)路由被訪問(wèn)到的時(shí)候,才會(huì)加載對(duì)應(yīng)組件的代碼塊,需要的朋友可以參考下
    2022-12-12
  • vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?different?content?to?the?same?filename?index.html問(wèn)題的解決辦法

    vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?dif

    最近vue/cli創(chuàng)建項(xiàng)目后出現(xiàn)了錯(cuò)誤,下面這篇文章主要給大家介紹了關(guān)于vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?different?content?to?the?same?filename?index.html問(wèn)題的解決辦法,需要的朋友可以參考下
    2023-02-02
  • vue和react中props變化后如何修改state

    vue和react中props變化后如何修改state

    這篇文章主要介紹了vue和react中props變化后如何修改state,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08

最新評(píng)論

宣恩县| 明溪县| 大埔区| 新沂市| 花垣县| 化州市| 新邵县| 成都市| 石渠县| 正安县| 张家界市| 景宁| 七台河市| 丹寨县| 华蓥市| 卢氏县| 瓦房店市| 淮安市| 洛阳市| 宜宾县| 云霄县| 武强县| 雷山县| 乐陵市| 九江市| 行唐县| 濮阳市| 凉山| 西藏| 新丰县| 城市| 什邡市| 右玉县| 云龙县| 镇赉县| 克什克腾旗| 横峰县| 隆林| 无为县| 崇左市| 裕民县|