創建 Vue 3.0 工程
使用 vue cli 創建
|
|
使用 vite 創建(Vue作者的團隊開發)
- 官方文檔:https://v3.cn.vuejs.org/guide/installation.html#vite
- vite官網:https://vitejs.cn/
- 優勢:
- 開發環境中,無需打包操作,可快速的冷啟動。
- 輕量快速的熱重載(HMR)。
- 真正的按需編譯,不再等待整個應用編譯完成。
- 傳統 grunt、gulp、webpack 與 vite 構建對比圖:
|
|
安裝 Vue 開發者工具
拉開序幕的 Setup
- Vue3.0 中一個新的配置項,值為一個函數。
- 是所有
Composition API (組合式API)
的表演舞台。 - 組件中所用到的數據、方法等等,均要配置在 setup 中。
- setup 函數的:
- 若返回一個對象,則對象中的屬性、方法,在模板中均可直接使用。(重點關注!)
- 若返回一個渲染函數,則可以自定義渲染內容。(了解即可)
返回對象
|
|
返回渲染函數(需引入 h
)
|
|
- 注意:
- 不要與Vue2.x配置混用。
- Vue2.x配置(data、methods、computed…)中可以訪問到setup中的屬性、方法,但在
setup
中不能訪問到Vue2.x配置(data、methods、computed…)。 - 如果有重名,setup優先。
- Vue2.x配置(data、methods、computed…)中可以訪問到setup中的屬性、方法,但在
- setup 不能是一個
async
函數,因為返回值不再是 return 的對象,而是一個promise
,模板看不到 return 對象中的屬性;後期可以返回一個 Promise 實例,但需要Suspense
與異步組件(動態組件)
的配合:點我前往 Suspense
ref 函數
- 作用:定義一個響應式的數據。
- 語法:
|
|
- 將數據加工成一個
RefImpl
(Reference: 引用;Implete: 實現) = (引用實現的實例對象)。 - js 中操作數據:
xxx.value
。 - 模板中讀取數據:
<div>{{xxx}}</div>
備註:
- 接收的數據可以是基本類型,也可以是對象類型。
- 基本類型的數據:響應式依然是靠
Object.defineProperty()
的get
與set
完成的。 - 對象類型的數據:內部求助了 Vue3.0 中的一個新函數—-
reactive
reactive 函數
- 作用:定義一個對象類型的響應式數據(基本類型別用他,用
ref
函數)。 - 語法:
|
|
- 接收一個對象或數組,返回一個代理對象(Proxy對象)。
- reactive 定義的響應式數據是
深層次的
。 - 內部基於 ES6 的 Proxy 實現,通過代理對象操作源對象內部數據都是響應式的,並通過
Reflect
操作源對象內部的數據。 - js、模板中操作數據均不需要
.value
Vue 2.0 中的響應式原理
實現原理:
- 對象類型:通過
Object.defineProperty()
對屬性的讀取、修改進行攔截(數據劫持)。 - 數組類型:通過重寫更新數組的一系列方式來實現攔截。(對數組的變更方法進行了包裹)。
|
|
原理模擬:
|
|
- 存在問題:
- 新增屬性、刪除屬性,介面不會更新,需使用
$set
、$delete
。 - 直接通過下標修改數組,介面不會更新,需使用
$set
、$delete
。
- 新增屬性、刪除屬性,介面不會更新,需使用
問題情況演示:
|
|
Vue 3.0 中的響應式原理
實現原理:
- 通過 Proxy(代理):攔截對象中任意屬性的變化,包含屬性值的讀寫、屬性的新增、屬性的刪除等。
- 通過 Reflect(反射):對被代理對象的屬性進行操作。
原理模擬:
|
|
setup 的兩個注意點
- setup 執行的時機:在 beforeCreate 之前執行一次,this 是 undefined。
- setup 的參數
props
:值為對象,包含:組件外部傳遞過來,且組件內部聲明接收了的屬性。context
:上下文對象:attrs
:值為對象,包含:組件外部傳遞過來,但沒有在 props 配置中聲明的屬性,相當於 Vue 2.0 的this.$attrs
。slots
:接收的插槽內容,相當於 Vue 2.0 的this.$slots
。emit
:分發自定義事件的函數,相當於 Vue 2.0 的this.$emit
。
watch 函數
- 與 Vue 2.0 中的 watch 配置功能一致。
- 兩個小"坑":
- 監視 ref 定義的響應式數據時,不需加
.value
。 - 監視 reactive 定義的響應式數據時,
oldValue
無法正確捕獲、強制開啟了深度監視(deep配置失效)。 - 監視 reactive 定義的響應式數據中的某個屬性時,deep 配置有效。
- 監視 ref 定義的響應式數據時,不需加
|
|
watch 時 value 的問題
- 若監視的數據為 ref 求助 reactive 生成的響應式數據,則可使用以下兩種方式進行監視:
|
|
watchEffect
- 智能版 watch,不用指名監視哪個屬性,監視的回調中用到哪個屬性,就監視哪個屬性(而且是深層次的)。
- watchEffect 有點像 computed:
- 但 computed 注重計算出來的值(回調函數的返回值),所以必須要寫返回值。
- 而 watchEffect 更注重的是過程(回調函數的函數體),所以不用寫返回值。
|
|
自定義 hook 函數
- hook 本質是一個函數,把 setup 函數中使用的 Composition API 進行了封裝。
- 類似於 vue 2.0 中的 mixin。
- 自定義 hook 的優勢:重複使用代碼,讓 setup 中的邏輯更清楚易懂。
- 命名通常建議以 “use” 開頭,例如:
一個獲取鼠標點擊位置的 hook
src/hooks/usePoint.js
|
|
Demo.vue
|
|
toRef
- 作用:創建一個 ref 對象,其 value 值指向(引用)另一個對象中的某個屬性(返回值為一個
ObjectRefImpl
對象,為響應式)。 - 語法:
|
|
- 應用:要將響應式對象中的某個屬性單獨提供給外部使用時。
- 擴展:
toRefs
與toRef
功能一致,但可以批量創建多個 ref 對象,語法:
|
|
使用範例:
|
|
其他的 Composition API
1. shallowReactive 與 shallowRef
- shallow:淺層的
- shallowReactive:只處理對象最外層屬性的響應式(淺響應式)。
- shallowRef:只處理基本數據類型的響應式,不進行對象的響應式處理。
- 什麼時候使用?
- 如果有一個對象數據,結構比較深,但變化時只是外層屬性變化 =>
shallowReactive
。 - 如果有一個對象數據,後續功能不會修改該對象中的屬性,而是生成新的對象來替換 =>
shallowRef
。
- 如果有一個對象數據,結構比較深,但變化時只是外層屬性變化 =>
|
|
2. readonly 與 shallowReadonly
- readonly:讓一個響應式數據變為唯讀的(深層唯讀)。
- shallowReadonly:讓一個響應式數據變為唯讀的(淺層唯讀)。
- 應用場景:不希望數據被修改時。
|
|
toRaw 與 markRaw
- raw:原始。
- toRaw:
- 作用:將一個由
reactive
生成的響應式對象
轉為普通對象
。 - 應用場景:用於讀取響應式對象對應的普通對象,對這個普通對象的所有操作,不會引起頁面更新。
- 作用:將一個由
- markRaw:
- 作用:標記一個對象,使其永遠不會再成為響應式對象。
- 應用場景:
- 有些值不應被設置為響應式的,例如複雜的第三方類庫等。
- 當渲染具有不可變數據源的大列表時,跳過響應式轉換可以提高性能。
|
|
customRef
- 作用:創建一個自定義的 ref,並對其依賴項跟蹤和更新觸發進行顯示控制。
- 實現防抖效果:
|
|
provide 與 inject
- 作用:實現祖孫組件間通信。
- 套路:父組件有一個
provide
選項來提供數據,後代組件有一個inject
選項來開始使用這些數據。 - 具體寫法:
1. 祖組件中:
|
|
2. 後代組件中:
|
|
響應式數據的判斷
- isRef:檢查一個值是否為一個
ref
對象。 - isReactive:檢查一個對象是否是由
reactive
創建的響應式代理。 - isReadonly:檢查一個對象是否是由
readonly
創建的唯讀代理。 - isProxy:檢查一個對象是否是由
reactive
或是readonly
方法創建的代理。
Teleport
- teleport:傳送、瞬間移動。
- 作用:能夠將我們的
組件 html 結構
移動到指定的位置。 - 具體寫法:
|
|
Suspense
- suspense:懸疑、懸而未決的。
- 作用:等待異步組件時,渲染一些額外內容,讓使用者有更好的用戶體驗。
- 使用步驟:
異步引用組件
|
|
使用 Suspense
包裹組件,並配置好 default
與 fallback
|
|
全局 API 的轉移
- Vue 2.0 有許多全局 API 和配置。
- 例如:註冊全局組件、註冊全局指令等。
|
|
- Vue 3.0 中對這些 API 做出了調整:
- 將全局的 API,即:
Vue.xxx
調整到應用實例(app
)上
- 將全局的 API,即:
2.0 全局 API(Vue ) | 3.0 實例 API(app ) |
---|---|
Vue.config.xxxx | app.config.xxxx |
Vue.config.productionTip | 移除 |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
Vue.prototype | app.config.globalProperties |