快速使用 Vue3 最新的 15 個常用 API

本文會頻繁地對比 Vue2 來介紹 Vue3,也將對各個 API 結合代碼實例講解,這既是對自己知識的總結,也希望能幫助到大家。

一、前言

大家都知道,現在 Vue3 的各個版本已經陸續發佈了,並且有很多的團隊已經着手各個庫的開發與 Vue2 向 Vue3 的升級,我們當然也不能落後,所以趕緊將你手中的 Vue2 升級到 Vue3,跟着本文一起學習新的 API 吧

升級的方法可以點擊本文開頭的文章,在上一篇文章中有個保姆級別的教程告訴大家如何升級

二、正文

Vue2 每次都把整個 Vue 導入,例如 Vue2 的 main.js 文件中的代碼

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App)
}).$mount('#app')

但很明顯我們的項目中不可能用到 Vue 所有的 API,因此很多模塊其實是沒有用的

那麼在 Vue3 中,對外暴露了很多的 API 供開發者使用,我們可以根據自己的需求,將所需要的 API 從 Vue 中導入。例如 main.js 中的代碼

import { createApp } from 'vue';
import App from './App.vue'

createApp(App).mount('#app')

利用了 importexport 的導入導出語法,實現了按需打包模塊的功能,項目打包後的文件體積明顯小了很多

這也是我們本文需要對 Vue3 API 進行詳細瞭解的原因

(1)setup

setup 函數也是 Composition API 的入口函數,我們的變量、方法都是在該函數里定義的,來看一下使用方法

<template>
  <div id="app">
      <p>{{ number }}</p>
      <button @click="add">增加</button>
  </div>
</template>

<script>
// 1. 從 vue 中引入 ref 函數
import {ref} from 'vue'
export default {
  name: 'App',
  setup() {
      // 2. 用 ref 函數包裝一個響應式變量 number
      let number = ref(0)

      // 3. 設定一個方法
      function add() {
          // number是被ref函數包裝過了的,其值保存在.value中
          number.value ++
      }

      // 4. 將 number 和 add 返回出去,供template中使用
      return {number, add}
  }
  
}
</script>

上述代碼中用到了 ref 函數,下面會詳細講解,在這裏你只需要理解它的作用是包裝一個響應式的數據即可,並且你可以將 ref 函數包裝過的變量看作是 Vue2 data 中的變量

這樣就簡單實現了一個點擊按鈕數字加 1 的功能


在 Vue2 中,我們訪問 dataprops 中的變量,都是通過類似 this.number 這樣的形式去獲取的,但要特別注意的是,在 setup 中,this 指向的是 undefined,也就是說不能再向 Vue2 一樣通過 this 去獲取變量了

那麼到底該如何獲取到 props 中的數據呢?

其實 setup 函數還有兩個參數,分別是 propscontext,前者存儲着定義當前組件允許外界傳遞過來的參數名稱以及對應的值;後者是一個上下文對象,能從中訪問到 attremitslots

其中 emit 就是我們熟悉的 Vue2 中與父組件通信的方法,可以直接拿來調用

(2)生命週期

Vue2 中有 beforeCreatecreatedbeforeMountmountedbeforeUpdate 等生命週期函數

而在 Vue3 中,這些生命週期部分有所變化,並且調用的方式也有所改變,下面放上一張變化圖來簡單瞭解一下

XY0zzC

Vue3 的這些生命週期調用也很簡單,同樣是先從 vue 中導入,再進行直接調用

<template>
  <div id="app"></div>
</template>

<script>
// 1. 從 vue 中引入 多個生命週期函數
import {onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, unMounted} from 'vue'
export default {
  name: 'App',
  setup() {
      onBeforeMount(() ={
          // 在掛載前執行某些代碼
      })

      onMounted(() ={
          // 在掛載後執行某些代碼
      })

      onBeforeUpdate(() ={
          // 在更新前前執行某些代碼
      })

      onUpdated(() ={
          // 在更新後執行某些代碼
      })

      onBeforeUnmount(() ={
          // 在組件銷燬前執行某些代碼
      })

      unMounted(() ={
          // 在組件銷燬後執行某些代碼
      })

      return {}
  }
  
}
</script>

(3)reactive

reactive 方法是用來創建一個響應式的數據對象,該 API 也很好地解決了 Vue2 通過 defineProperty 實現數據響應式的缺陷

用法很簡單,只需將數據作爲參數傳入即可,代碼如下

<template>
  <div id="app">
   <!-- 4. 訪問響應式數據對象中的 count  -->
   {{ state.count }}
  </div>
</template>

<script>
// 1. 從 vue 中導入 reactive 
import {reactive} from 'vue'
export default {
  name: 'App',
  setup() {
      // 2. 創建響應式的數據對象
      const state = reactive({count: 3})

      // 3. 將響應式數據對象state return 出去,供template使用
      return {state}
  }
}
</script>

(4)ref

在介紹 setup 函數時,我們使用了 ref 函數包裝了一個響應式的數據對象,這裏表面上看上去跟 reactive 好像功能一模一樣啊,確實差不多,因爲 ref 就是通過 reactive 包裝了一個對象 ,然後是將值傳給該對象中的 value 屬性,這也就解釋了爲什麼每次訪問時我們都需要加上 .value

我們可以簡單地把 ref(obj) 理解爲這個樣子 reactive({value: obj})

這裏我們寫一段代碼來具體看一下

<script>
import {ref, reactive} from 'vue'
export default {
  name: 'App',
  setup() {
      const obj = {count: 3}
      const state1 = ref(obj)
      const state2 = reactive(obj)

      console.log(state1)
      console.log(state2)
  }
  
}
</script>

來看一下打印結果

注意: 這裏指的 .value 是在 setup 函數中訪問 ref 包裝後的對象時才需要加的,在 template 模板中訪問時是不需要的,因爲在編譯時,會自動識別其是否爲 ref 包裝過的

那麼我們到底該如何選擇 refreactive 呢?

建議:

  1. 基本類型值(StringNmuberBoolean 等)或單值對象(類似像 {count: 3} 這樣只有一個屬性值的對象)使用 ref

  2. 引用類型值(ObjectArray)使用 reactive

(5)toRef

toRef 是將某個對象中的某個值轉化爲響應式數據,其接收兩個參數,第一個參數爲 obj 對象;第二個參數爲對象中的屬性名

代碼如下:

<script>
// 1. 導入 toRef
import {toRef} from 'vue'
export default {
    setup() {
        const obj = {count: 3}
        // 2. 將 obj 對象中屬性count的值轉化爲響應式數據
        const state = toRef(obj, 'count')

        // 3. 將toRef包裝過的數據對象返回供template使用
        return {state}
    }
}
</script>

但其實表面上看上去 toRef 這個 API 好像非常的沒用,因爲這個功能也可以用 ref 實現,代碼如下

<script>
// 1. 導入 ref
import {ref} from 'vue'
export default {
    setup() {
        const obj = {count: 3}
        // 2. 將 obj 對象中屬性count的值轉化爲響應式數據
        const state = ref(obj.count)

        // 3. 將ref包裝過的數據對象返回供template使用
        return {state}
    }
}
</script>

乍一看好像還真是,其實這兩者是有區別的,我們可以通過一個案例來比較一下,代碼如下

<template>
    <p>{{ state1 }}</p>
    <button @click="add1">增加</button>

 <p>{{ state2 }}</p>
    <button @click="add2">增加</button>
</template>

<script>
import {ref, toRef} from 'vue'
export default {
    setup() {
        const obj = {count: 3}
        const state1 = ref(obj.count)
        const state2 = toRef(obj, 'count')

        function add1() {
            state1.value ++
            console.log('原始值:', obj);
            console.log('響應式數據對象:', state1);
        }

        function add2() {
            state2.value ++
            console.log('原始值:', obj);
            console.log('響應式數據對象:', state2);
        }

        return {state1, state2, add1, add2}
    }
}
</script>

我們分別用 reftoRefobj 中的 count 轉化爲響應式,並聲明瞭兩個方法分別使 count 值增加,每次增加後打印一下原始值 obj 和被包裝過的響應式數據對象,同時還要看看視圖的變化

ref:

可以看到,在對響應式數據的值進行 +1 操作後,視圖改變了,原始值未改變,響應式數據對象的值也改變了,這說明 ref 是對原數據的一個拷貝,不會影響到原始值,同時響應式數據對象值改變後會同步更新視圖

toRef:

可以看到,在對響應式數據的值進行 +1 操作後,視圖未發生改變,原始值改變了,響應式數據對象的值也改變了,這說明 toRef 是對原數據的一個引用,會影響到原始值,但是響應式數據對象值改變後會不會更新視圖

總結:

  1. ref 是對傳入數據的拷貝;toRef 是對傳入數據的引用

  2. ref 的值改變會更新視圖;toRef 的值改變不會更新視圖

(6)toRefs

瞭解完 toRef 後,就很好理解 toRefs 了,其作用就是將傳入的對象裏所有的屬性的值都轉化爲響應式數據對象,該函數支持一個參數,即 obj 對象

我們來看一下它的基本使用

<script>
// 1. 導入 toRefs
import {toRefs} from 'vue'
export default {
    setup() {
        const obj = {
            name: '前端印象',
            age: 22,
            gender: 0
        }
        // 2. 將 obj 對象中屬性count的值轉化爲響應式數據
        const state = toRefs(obj)

        // 3. 打印查看一下
        console.log(state)
    }
}
</script>

打印結果如下:

返回的是一個對象,對象裏包含了每一個包裝過後的響應式數據對象

(7)shallowReactive

聽這個 API 的名稱就知道,這是一個淺層的 reactive,難道意思就是原本的 reactive 是深層的唄,沒錯,這是一個用於性能優化的 API

其實將 obj 作爲參數傳遞給 reactive 生成響應式數據對象時,若 obj 的層級不止一層,那麼會將每一層都用 Proxy 包裝一次,我們來驗證一下

<script>
import {reactive} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = reactive(obj)

        console.log(state)
        console.log(state.first)
        console.log(state.first.second)
    }
}
</script>

來看一下打印結果:

設想一下如果一個對象層級比較深,那麼每一層都用 Proxy 包裝後,對於性能是非常不友好的

接下來我們再來看看 shallowReactive

<script>
import {shallowReactive} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowReactive(obj)

        console.log(state)
        console.log(state.first)
        console.log(state.first.second)
    }
}
</script>

來看一下打印結果:

結果非常的明瞭了,只有第一層被 Proxy 處理了,也就是說只有修改第一層的值時,纔會響應式更新,代碼如下:

<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change1">改變1</button>
 <button @click="change2">改變2</button>
</template>
<script>
import {shallowReactive} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowReactive(obj)

        function change1() {
            state.a = 7
        }

        function change2() {
            state.first.b = 8
            state.first.second.c = 9
            console.log(state);
        }

        return {state}
    }
}
</script>

來看一下具體過程:

首先我們點擊了第二個按鈕,改變了第二層的 b 和第三層的 c,雖然值發生了改變,但是視圖卻沒有進行更新;

當我們點擊了第一個按鈕,改變了第一層的 a 時,整個視圖進行了更新;

由此可說明,shallowReactive 監聽了第一層屬性的值,一旦發生改變,則更新視圖

(8)shallowRef

這是一個淺層的 ref,與 shallowReactive 一樣是拿來做性能優化的

shallowReactive 是監聽對象第一層的數據變化用於驅動視圖更新,那麼 shallowRef 則是監聽 .value 的值的變化來更新視圖的

我們來看一下具體代碼

<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change1">改變1</button>
 <button @click="change2">改變2</button>
</template>

<script>
import {shallowRef} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowRef(obj)
        console.log(state);

        function change1() {
            // 直接將state.value重新賦值
            state.value = {
                a: 7,
                first: {
                    b: 8,
                    second: {
                        c: 9
                    }
                }
            }
        }

        function change2() {
            state.value.first.b = 8
            state.value.first.second.c = 9
            console.log(state);
        }

        return {state, change1, change2}
    }
}
</script>

首先看一下被 shallowRef 包裝過後是怎樣的結構

然後再來看看改變其值會有什麼變化

我們先點擊了第二個按鈕,發現數據確實被改變了,但是視圖並沒隨之更新;

於是點擊了第一個按鈕,即將整個 .value 重新賦值了,視圖就立馬更新了

這麼一看,未免也太過麻煩了,改個數據還要重新賦值,不要擔心,此時我們可以用到另一個 API,叫做 triggerRef ,調用它就可以立馬更新視圖,其接收一個參數 state ,即需要更新的 ref 對象

我們來使用一下

<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change">改變</button>
</template>

<script>
import {shallowRef, triggerRef} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowRef(obj)
        console.log(state);

        function change() {
            state.value.first.b = 8
            state.value.first.second.c = 9
            // 修改值後立即驅動視圖更新
            triggerRef(state)
            console.log(state);
        }

        return {state, change}
    }
}
</script>

我們來看一下具體過程

可以看到,我們沒有給 .value 重新賦值,只是在修改值後,調用了 triggerRef 就實現了視圖的更新

(9)toRaw

toRaw 方法是用於獲取 refreactive 對象的原始數據的

先來看一段代碼

<template>
 <p>{{ state.name }}</p>
 <p>{{ state.age }}</p>
 <button @click="change">改變</button>
</template>

<script>
import {reactive} from 'vue'
export default {
    setup() {
        const obj = {
            name: '前端印象',
            age: 22
        }

        const state = reactive(obj) 

        function change() {
            state.age = 90
            console.log(obj); // 打印原始數據obj
            console.log(state);  // 打印 reactive對象
        }

        return {state, change}
    }
}
</script>

來看看具體過程

我們改變了 reactive 對象中的數據,於是看到原始數據 obj 和被 reactive 包裝過的對象的值都發生了變化,由此我們可以看出,這兩者是一個引用關係

那麼此時我們就想了,那如果直接改變原始數據 obj 的值,會怎麼樣呢?答案是:reactive 的值也會跟着改變,但是視圖不會更新

由此可見,當我們想修改數據,但不想讓視圖更新時,可以選擇直接修改原始數據上的值,因此需要先獲取到原始數據,我們可以使用 Vue3 提供的 toRaw 方法

toRaw 接收一個參數,即 ref 對象或 reactive 對象

<script>
import {reactive, toRaw} from 'vue'
export default {
    setup() {
        const obj = {
            name: '前端印象',
            age: 22
        }

        const state = reactive(obj) 
        const raw = toRaw(state)

        console.log(obj === raw)   // true
    }
}
</script>

上述代碼就證明了 toRaw 方法從 reactive 對象中獲取到的是原始數據,因此我們就可以很方便的通過修改原始數據的值而不更新視圖來做一些性能優化了

注意: 補充一句,當 toRaw 方法接收的參數是 ref 對象時,需要加上 .value 才能獲取到原始數據對象

(10)markRaw

markRaw 方法可以將原始數據標記爲非響應式的,即使用 refreactive 將其包裝,仍無法實現數據響應式,其接收一個參數,即原始數據,並返回被標記後的數據

我們來看一下代碼

<template>
 <p>{{ state.name }}</p>
 <p>{{ state.age }}</p>
 <button @click="change">改變</button>
</template>

<script>
import {reactive, markRaw} from 'vue'
export default {
    setup() {
        const obj = {
            name: '前端印象',
            age: 22
        }
        // 通過markRaw標記原始數據obj, 使其數據更新不再被追蹤
        const raw = markRaw(obj)   
        // 試圖用reactive包裝raw, 使其變成響應式數據
        const state = reactive(raw) 

        function change() {
            state.age = 90
            console.log(state);
        }

        return {state, change}
    }
}
</script>

我們來看一下在被 markRaw 方法處理過後的數據是否還能被 reactive 包裝成響應式數據

從圖中可以看到,即使我們修改了值也不會更新視圖了,即沒有實現數據響應式

(11)provide && inject

與 Vue2 中的 provideinject 作用相同,只不過在 Vue3 中需要手動從 vue 中導入

這裏簡單說明一下這兩個方法的作用:

假設這有三個組件,分別是 A.vueB.vueC.vue,其中 B.vueA.vue 的子組件,C.vueB.vue 的子組件

// A.vue
<script>
import {provide} from 'vue'
export default {
    setup() {
        const obj= {
            name: '前端印象',
            age: 22
        }

        // 向子組件以及子孫組件傳遞名爲info的數據
        provide('info', obj)
    }
}
</script>

// B.vue
<script>
import {inject} from 'vue'
export default {
    setup() { 
        // 接收A.vue傳遞過來的數據
        inject('info')  // {name: '前端印象', age: 22}
    }
}
</script>

// C.vue
<script>
import {inject} from 'vue'
export default {
    setup() { 
        // 接收A.vue傳遞過來的數據
        inject('info')  // {name: '前端印象', age: 22}
    }
}
</script>

(12)watch && watchEffect

watchwatchEffect 都是用來監視某項數據變化從而執行指定的操作的,但用法上還是有所區別

watch:watch(source, cb, [options] )

參數說明:

當監聽 ref 類型時:

<script>
import {ref, watch} from 'vue'
export default {
    setup() { 
        const state = ref(0)

        watch(state, (newValue, oldValue) ={
            console.log(`原值爲${oldValue}`)
            console.log(`新值爲${newValue}`)
            /* 1秒後打印結果:
                            原值爲0
                            新值爲1
            */
        })

        // 1秒後將state值+1
        setTimeout(() ={
            state.value ++
        }, 1000)
    }
}
</script>

當監聽 reactive 類型時:

<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({count: 0})

        watch(() => state.count, (newValue, oldValue) ={
            console.log(`原值爲${oldValue}`)
            console.log(`新值爲${newValue}`)
            /* 1秒後打印結果:
                            原值爲0
                            新值爲1
            */
        })

        // 1秒後將state.count的值+1
        setTimeout(() ={
            state.count ++
        }, 1000)
    }
}
</script>

當同時監聽多個值時:

<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({ count: 0, name: 'zs' })

        watch(
            [() => state.count, () => state.name], 
            ([newCount, newName][oldvCount, oldvName]) ={
                console.log(oldvCount) // 舊的 count 值
                console.log(newCount) // 新的 count 值
                console.log(oldName) // 舊的 name 值
                console.log(newvName) // 新的 name 值
            }
        )

        setTimeout(() ={
          state.count ++
          state.name = 'ls'
        }, 1000)
    }
}
</script>

因爲 watch 方法的第一個參數我們已經指定了監聽的對象,因此當組件初始化時,不會執行第二個參數中的回調函數,若我們想讓其初始化時就先執行一遍,可以在第三個參數對象中設置 immediate: true

watch 方法默認是漸層的監聽我們指定的數據,例如如果監聽的數據有多層嵌套,深層的數據變化不會觸發監聽的回調,若我們想要其對深層數據也進行監聽,可以在第三個參數對象中設置 deep: true

補充: watch 方法會返回一個 stop 方法,若想要停止監聽,便可直接執行該 stop 函數


接下來再來聊聊 watchEffect,它與 watch 的區別主要有以下幾點:

  1. 不需要手動傳入依賴

  2. 每次初始化時會執行一次回調函數來自動獲取依賴

  3. 無法獲取到原值,只能得到變化後的值

來看一下該方法如何使用:

<script>
import {reactive, watchEffect} from 'vue'
export default {
    setup() { 
        const state = reactive({ count: 0, name: 'zs' })

        watchEffect(() ={
            console.log(state.count)
            console.log(state.name)
            /*  初始化時打印:
                            0
                            zs

                1秒後打印:
                            1
                            ls
            */
        })

        setTimeout(() ={
          state.count ++
          state.name = 'ls'
        }, 1000)
    }
}
</script>

從上述代碼中可以看出,我們並沒有像 watch 方法一樣先給其傳入一個依賴,而是直接指定了一個回調函數

當組件初始化時,將該回調函數執行一次,自動獲取到需要檢測的數據是 state.countstate.name

根據以上特徵,我們可以自行選擇使用哪一個監聽器

(13)getCurrentInstance

我們都知道在 Vue2 的任何一個組件中想要獲取當前組件的實例可以通過 this 來得到,而在 Vue3 中我們大量的代碼都在 setup 函數中運行,並且在該函數中 this 指向的是 undefined,那麼該如何獲取到當前組件的實例呢?

這時可以用到另一個方法,即 getCurrentInstance

<template>
 <p>{{ num }}</p>
</template>
<script>
import {ref, getCurrentInstance} from 'vue'
export default {
    setup() { 
        const num = ref(3)
        const instance = getCurrentInstance()
        console.log(instance)

        return {num}
    }
}
</script>

我們來看一下其打印結果

因爲 instance 包含的內容太多,所以沒截完整,但是主要的內容都在圖上了,我們重點來看一下 ctxproxy,因爲這兩個纔是我們想要的 this 的內容

可以看到 ctxproxy 的內容十分類似,只是後者相對於前者外部包裝了一層 proxy,由此可說明 proxy 是響應式的

(14)useStore

在 Vue2 中使用 Vuex,我們都是通過 this.$store 來與獲取到 Vuex 實例,但上一部分說了原本 Vue2 中的 this 的獲取方式不一樣了,並且我們在 Vue3 的 getCurrentInstance().ctx 中也沒有發現 $store 這個屬性,那麼如何獲取到 Vuex 實例呢?這就要通過 vuex 中的一個方法了,即 useStore

// store 文件夾下的 index.js
import Vuex from 'vuex'

const store = Vuex.createStore({
    state: {
        name: '前端印象',
        age: 22
    },
    mutations: {
        ……
    },
    ……
})

// example.vue
<script>
// 從 vuex 中導入 useStore 方法
import {useStore} from 'vuex'
export default {
    setup() { 
        // 獲取 vuex 實例
        const store = useStore()

        console.log(store)
    }
}
</script>

我們來看一下打印結果

然後接下來就可以像之前一樣正常使用 vuex

(15)獲取標籤元素

最後再補充一個 ref 另外的作用,那就是可以獲取到標籤元素或組件

在 Vue2 中,我們獲取元素都是通過給元素一個 ref 屬性,然後通過 this.$refs.xx 來訪問的,但這在 Vue3 中已經不再適用了

接下來看看 Vue3 中是如何獲取元素的吧

<template>
  <div>
    <div ref="el">div元素</div>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
export default {
  setup() {
      // 創建一個DOM引用,名稱必須與元素的ref屬性名相同
      const el = ref(null)

      // 在掛載後才能通過 el 獲取到目標元素
      onMounted(() ={
        el.value.innerHTML = '內容被修改'
      })

      // 把創建的引用 return 出去
      return {el}
  }
}
</script>

獲取元素的操作一共分爲以下幾個步驟:

  1. 先給目標元素的 ref 屬性設置一個值,假設爲 el

  2. 然後在 setup 函數中調用 ref 函數,值爲 null,並賦值給變量 el,這裏要注意,該變量名必須與我們給元素設置的 ref 屬性名相同

  3. 把對元素的引用變量 el 返回(return)出去

補充:設置的元素引用變量只有在組件掛載後才能訪問到,因此在掛載前對元素進行操作都是無效的

當然如果我們引用的是一個組件元素,那麼獲得的將是該組件的實例對象,這裏就不做過多的演示了

三、結束語

本文也是筆者對 Vue3 的學習與理解。因爲在之前學習的過程中也查閱了大量的文檔資料,並不斷地測試摸索,以及在 Vue3 項目中的心得體會,都讓我對 Vue3 有了更深的認識,與此同時,我在各個社區或者是社交羣裏都發現很多小夥伴對 Vue3 的 API 都不太熟悉,甚至不知道有這些 API,所以我就寫下了這篇總結文章,將我所知道、所理解的都分享給大家。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/IIs3JJZTjJhTmmoSwXb9Cw