Vue3 - useful features 實用工具解析
本篇重點說明 Vue3 幾個好用的語法糖,包涵
又來到填坑的好時機了,這篇來重點介紹一下 Vue3 釋出的幾個好用的小工具來加快業務邏輯開發的效率,也可以更靈活的擴大 props 的應用,快來瞧瞧吧!
WatchEffect
該函式範圍內的依賴(Dependency)都會被直接偵測到並且觸發副作用,不需要特地撰寫 immediate: true
、 deep: true
與指定依賴(Source),大大的助益了多個依賴時的維護度。
簡而言之就是包含了以下額外配置的用法: 1. `immediate: true` 2. `deep: true` 3. 多重 source 監聽
watchEffect
only tracks dependencies during its synchronous execution. When using it with an async callback, only properties accessed before the first await tick will be tracked.
同步執行的程式才會追蹤依賴(Dependency)變化,若以非同步形式async
撰寫 Callback 則第一個await
之前被監聽的依賴(Source)才會被追蹤。
watchEffect v.s. Watch
Watch is lazy by default: the callback won’t be called until the watched source has changed.
watch 若沒有指定immediate: true
則第一次的創造 watcher 時不會觸發,mounted 階段則沒有改變。
watchEffect 會自動在第一次就監聽到變化,可以節省撰寫 immediate 或者 mounted 額外執行第一次的行為,另外重要的一點是 watchEffect 只追蹤 Callback 觸及的 Source。
Component features
defineProps & withDefaults
defineProps 官方文件
應用上主要為了解決型別的定義(Typescript)而產生。
defineProps
定義 props 的型別小工具,基礎用法。
1 | const props = defineProps({ |
withDefaults
處理解構後的預設值(default props),可以清楚分開定義型別與預設值,搭配 defineProps
的進階用法。
1 | const props = withDefaults( |
attrs & v-bind
attrs 官方文件attr
& v-bind
是全開 props 的雙刀流,當使用三方 UI 套件時不限制元件的 props 資料可用,父元件傳的資料全盤接收到子元件上,擴展使用靈活度。
- 使用 useAttrs() API 取得所有 props attributes。
- 將元件 v-bind 傳入資料。
1
2
3
4
5
6
7
8
9
10
11
12<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
const getBindValues = computed(() => ({
...attrs,
otherData: 'other props'
}))
</script>
<template>
<el-component v-bind="getBindValues"></el-component>
</template>
useVModel
Shorthand for v-model binding, props + emit -> ref
我的理解是讓元件props
&emit
也能落實V-model
的雙向綁定效果,省略事件綁定的 boilerplate。
不使用 useVModel
需要撰寫完整的監聽事件與 emit 方法。
1 | <template> |
使用 useVModel
是需要透過 @vueuse/core
漸進式導入的額外工具
1 | import { useVModel } from '@vueuse/core' |
useVModel 在 @vueuse/core
有單一資料與 multiple 資料(useVModels 就是 useVModel loop)可以使用, 以 v-model 形式撰寫雙向資料綁定:
參數列表
props
為父元件傳遞的defineProps()
資料串key
為props[key]
的值,選擇需要綁定的 prop 資料- emit 為子元件響應的
defineEmits()
對應事件
export function useVModel<P extends object, K extends keyof P, Name extends string>(
props: P,
key?: K,
emit?: (name: Name, …args: any[]) => void,
options?: UseVModelOptions<P[K], false>,
): WritableComputedRef<P[K]>
1 | <template> |
defineModel
defineModel 官方文件
Vue 推出的 3.4 版本釋出的巨集(Macro)工具之一,不需匯入就可以使用,算是 V-model 在元件內的另一種進化版用法,常用在 集合 Form inputs。
If you have a default value for defineModel prop and you don’t provide any value for this prop from the parent component, it can cause a de-synchronization between parent and child components.
文件有提醒記得在父元件提供預設值(default values)否則會導致父子元件資料不同步的問題。
Component 子元件
定義一個 defineModel
對象並制定表單項目。
1 | <script setup lang="ts"> |
Parent 父元件
制定一樣規格的資料傳進子元件中並設定好預設值。
1 | <script setup lang="ts"> |
比較 useVModel & defineModel
useVModel
- useVModel is a function that takes in the component’s props and emits function, and it returns a reactive reference that can be bound to v-model.
- abstracts away the need to manually emit the update:modelValue event.
從 VueUse(core) 外部引用的工具,提供給 Composition API 使用,取得元件的 props & emits 並且回傳一個 model 對象提供綁定,減少 update value 的 emit 事件制定步驟。
defineModel
- defineModel allows you to declare a v-model binding directly in the component’s props, making it explicit and simplifying the logic for handling model bindings.
- It automatically handles the prop and event emission, reducing boilerplate code.
是官方釋出的巨集(Macro)的工具之一,允許在子元件直接雙向綁定省去處理 props & emits,Composition 與 Options APIs 都適用,會是一個比 useVModel 更簡潔的寫法,不過 useVModel 可以自定義更複雜的邏輯處理。