Vue2 到 Vue3,重溫這 5 個常用的 API
距離Vue3發布已經過去一年多時間了,從Vue2到Vue3是一個不小的升級,包括周邊生態等。雖然目前大多數開發者們在使用的仍舊以
Vue2
為準,但Vue3顯然是Vue開發者們未來必須面對的,而且前不久Vue官方也發布了Vue2.7.0,使得Vue2可以兼容Vue3的API,這讓開發者可以在項目不升級Vue3的情況下依舊可以使用Vue3的開發方式,這為Vue2開發者學習Vue3提供了一個非常好的過渡途徑。
Vue3之於Vue2最大的變化,當屬composition API
了,而除了引入composition API
外,一些我們在Vue2上經常使用的東西到了Vue3時也發生了不小的變化,本文將介紹一些有Vue2到Vue3中幾個比較重要且常用的知識點,歡迎感興趣的同學閱讀。
文中程式碼示例使用
setup語法糖 + ts
v-model
支援多個v-model
在Vue3
中,可以通過參數來達到一個組件支援多個v-model
的能力。
// 父組件
<template>
<child v-model="name" v-model:email="email" />
<p>姓名:{{ name }}</p>
<p>郵箱:{{ email }}</p>
</template>
<script lang="ts" setup>
import child from './child.vue'
import { ref } from 'vue'
const name = ref<string>('張三')
const email = ref<string>('[email protected]')
</script>
複製程式碼
// 子組件
<template>
<button @click="updateName">更新name</button>
<button @click="updateEmail">更新email</button>
</template>
<script lang="ts" setup>
// 定義emit
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void
(e: 'update:email', value: string): void
}>()
const updateName = () => {
emits('update:modelValue', '李四')
}
const updateEmail = () => {
emits('update:email', '[email protected]')
}
</script>
如果v-model
沒有使用參數,則其默認值為modelValue
,如上面的第一個v-model
,注意此時不再是像Vue2那樣使用$emit('input')
了,而是統一使用update:xxx
的方式。
廢棄.sync
在Vue2中,由於一個組件只支援一個v-model
,當我們還有另外的值也想要實現雙向綁定更新時,往往用.sync
修飾符來實現,而在Vue3中該修飾符已被廢棄,因為v-model
可以支援多個,所以.sync
也就沒有存在的必要了。
watch
不同數據類型的監聽
基礎數據類型的監聽:
const name = ref<string>('張三')
watch(name, (newValue, oldValue) => {
console.log('watch===', newValue, oldValue)
})
複製程式碼
複雜數據類型的監聽:
interface UserInfo {
name: string
age: number
}
const userInfo = reactive<UserInfo>({
name: '張三',
age: 10
})
// 監聽整個對象
watch(userInfo, (newValue, oldValue) => {
console.log('watch userInfo', newValue, oldValue)
})
// 監聽某個屬性
watch(() => userInfo.name, (newValue, oldValue) => {
console.log('watch name', newValue, oldValue)
})
支援監聽多個源
在Vue3
里,watch
多了一個特性,可以傳入一個數組同時偵聽多個數據,這比起Vue2
確實優雅多了,以往在Vue2
中為了實現同時監聽多個數據,往往需要藉助computed,現在在Vue3里我們可以少一些不必要的程式碼了。
const name = ref<string>('張三')
const userInfo = reactive({
age: 18
})
// 同時監聽name和userInfo的age屬性
watch([name, () => userInfo.age], ([newName, newAge], [oldName, oldAge]) => {
//
})
watchEffect
watchEffect與watch的區別
相比Vue2
,Vue3多
了watchEffect
這個API,watchEffect
傳入一個函數參數,該函數會立即執行,同時會響應式的最終函數內的依賴變數,並在依賴發生改變時重新運行改函數。
const name = ref<string>('張三')
const age = ref<number>(18)
watchEffect(() => {
console.log(`${name.value}:${age.value}`) // 張三:18
})
setTimeout(() => {
name.value = '李四' // 李四:18
}, 3000)
setTimeout(() => {
age.value = 20 // 李四:20
}, 5000)
和watch的區別:
- 運行時機不同,
watchEffect
會立即執行,相當於設置了immediate: true
的watch
。 watchEffect
無法獲取改變前後的值。- 與
watch
顯示的指定依賴源不同,watchEffect
會自動收集依賴源。
用watchEffect
還是watch
?
建議在大部分時間裡使用watch
,避免一些不必要的重複觸發。
$attrs
Vue3中,$attrs
包含父組件中除props和自定義事件外的所有屬性集合。
不同於Vue2
,$attrs
包含了父組件的事件,因此$listenners
則被移除了。
// 父組件
<template>
<child id="root" class="test" name="張三" @confirm="getData" />
</template>
<script lang="ts" setup>
const getData = () => {
console.log('log')
}
</script>
// 子組件
<template>
<div>
<span>hello:{{ props.name }}</span>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs: false
}
</script>
<script lang="ts" setup>
const props = defineProps(['name'])
const attrs = useAttrs()
console.log('attrs', attrs)
</script>
使用v-bind
即可實現組件屬性及事件透傳:
// 父組件
<template>
<child closeable @close="onClose" />
</template>
<script lang="ts" setup>
const onClose = () => {
console.log('close')
}
</script>
// 子組件
<template>
<div>
<el-tag v-bind="attrs">標籤</el-tag>
</div>
</template>
使用ref
訪問子組件
在Vue2
中,使用ref
即可訪問子組件里的任意數據及方法,但在Vue3
中則必須使用defineExpose
暴露子組件內的方法或屬性才能被父組件所調用。
// 父組件
<template>
<child ref="childRef" />
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
const childRef = ref()
onMounted(() => {
childRef.value.getData()
})
</script>
// 子組件
<script lang="ts" setup>
import { defineExpose } from 'vue'
const getData = () => {
console.log('getData')
}
const name = ref('張三')
defineExpose({
getData,
name
})
</script>
感謝
本次分享就到此結束了,感謝您的閱讀!!!如有什麼不到位的地方還望大佬不吝賜教!!!江湖最高禮儀