關於 Vue3 組合式 API 的一些看法


前言

在學習Vue的時候,最開始都是會從選項式API開始學起,到了后邊官方給出了 Vue3 的新方式 —— 組合式API。相信會有不少人跟我一樣,第一次聽到新的名詞時陷入了困擾。那么,什么是組合式API呢?

選項式API的壞處

代碼碎片化

通常在維護和開發一個組件時,分為 data、methods、computed、props 等。假如有一些業務在選項 API 的 data、methods、computed 中進行操作。把要關注的相同視角分別用不同顏色的框子框起來,發現我們的關注點被拆分成了這樣:

先不說大組件的關注點會被拆分成怎么樣,就單純這一個很簡單的演示就能夠讓各位同志體會到選項式 API 的壞處了。當我們的組件開始變得更大時,邏輯關注點的列表也會增長。如果你是一個軍隊的指揮官,你會選擇把戰線拉得很長嗎?費時費力,后勤補給也跟不上。

這種碎片化使得理解和維護復雜組件變得困難,選項的分離掩蓋了潛在的邏輯問題。此外,在處理單個邏輯關注點時,我們必須不斷地“跳轉”相關代碼的選項塊。

邏輯不復用

選項式API使代碼變得碎片化,曾經我想過把一段多次使用到的業務代碼抽離到一個單獨的 js 文件里。我遇到過一些困擾的小問題。首先,在 data 選項聲明的變量才是響應式數據。其次,在 methods 選項聲明的函數才可以操控組件里的響應式數據。這是下文分析選項式API邏輯不復用時的重要前提條件。

在 demo.js 文件里,我定義了一個 a 變量,calc 函數改變 a 的值:

export let a = 'foo'
export function calc() { a = a + 'bar' }

對於這樣的抽離方式,在使用的時候,依舊是需要把變量導入到 data 選項,使其成為響應式數據;函數導入到 methods 選項。

import { a, calc } from './demo.js'
export default {
    data() { return { a } },
    methods: { _calc() { calc() } }
}

由於 demo.js 文件里的函數操作的是 demo.js 文件里的變量 a ,而不是組件中響應式數據 a。導致我點擊了按鈕之后頁面未作出任何反應。

解決方法是,calc 函數接受一個形參,然后再返回。當然可以!這只是一個簡單的字符拼接而已。但是,這不是非常直接的辦法,要經歷一些曲折,同樣會導致代碼難讀懂的問題。

官方提供的解決方案是混入,而混入還是在寫選項API。不再選項API!不再選項API!不再選項API!,因為不符合期望。讀到這里,想必知道了選項式API的壞處了。

一句話總結選項式API的壞處就是:代碼碎片化、邏輯不復用

組合式API的好處

代碼集中化

為什么組合式API就可以讓代碼不碎片化呢?因為組合式API的組合就在於它把變量、函數集中在一起,減少分離掩蓋的潛在的邏輯問題,不在“跳轉”相關代碼的選項塊。

所以,是如何集中化的呢?因為 Vue3 要實現代碼集中化,所以,Vue3 的許多選項都抽離成為了一個個模塊(這是我的猜想,因為每次用到什么必須從 vue 模塊導入什么)。

組合式API就是一個 setup 函數,我們的所有代碼全部都要寫在這里面。

import { ref } from 'vue'
export default {
	setup() {
        let a = ref('foo')
        function calcA() { a.value = a.value + 'bar' }
        let b = ref('bar')
        function calcB() { b.value = b.value + 'foo' }
        let c = ref('hello')
        function calcC() { c.value = c.value + 'world' }
        let d = ref('world')
       	function calcD() { d.value = d.value + 'hello' }
	}
}

現在,我們的關注點會被集中化,用圖表示就是:

不知道各位是否有感受到這種變化,筆者已經感受到組合式API的強大了。

邏輯高復用

還記得第一章第二小節說到的問題嗎?Vue3 的許多選項都抽離成為了一個個模塊,所以我們可以在一個單獨的 js 聲明響應式數據了,就是利用 ref 函數來操作的。

我們新建一個 demo2.js 文件,首先引入 vue 模塊中的 ref 函數,用於聲明一個響應式數據:

import { ref } from 'vue'
export let a = ref('foo')
export function calc() { a.value = a.value + 'bar' }

然后我們在其他組件中使用:

import { a, calc } from './demo2.js'
export default {
    setup() {
        return { a, calc } // 這里需要導出a和calc
    }
}

由於在 demo2.js 的 calc 函數操作的已經是一個響應式數據了,所以,組件一旦用到了這個模塊中的東西,它都會反映到頁面中。

大功告成,這得益於 Vue3 的一大進步啊!現在我們寫代碼可以寫得非常舒服了。再加上 Vue3 是 TS 重構的,按道理來說是非常支持 TS 的寫法的,前提是你的項目支持 TS。

總結

將同一個邏輯關注點相關代碼收集在一起,在處理單個邏輯關注點時,我們必須不斷地“跳轉”相關代碼的選項塊。使得開發人員更容易閱讀和理解這些代碼,這正是組合式 API 要解決的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM