Vue3 的語法糖
組合式 API:setup()
Vue 3 的 Composition API
系列裏,推出了一個全新的 setup 函數,它是一個組件選項,在創建組件之前執行,一旦 props
被解析,並作爲組合式 API 的入口點。
setup 是一個接收props
和context
的函數,最後 setup 需要return
所有內容暴露給模板。
<script>
// 這是一個基於 TypeScript 的 Vue 組件
import { defineComponent } from 'vue'
export default defineComponent({
setup(props, context) {
// 在這裏聲明數據,或者編寫函數並在這裏執行它
console.log(context)
return {
// 需要給 `<template />` 用的數據或函數,在這裏 `return` 出去
}
},
})
</script>
新的 setup
選項是在組件創建之前, props
被解析之後執行,是組合式 API 的入口。
- 注意:在
setup
中不能使用this
,因爲他找不到實例。但是在 vue2 語法和 vue3 語法混用的時候,vue2 語法中可以使用this
訪問到setup
裏暴露出的變量。
組件的生命週期
可以看到 Vue 2 生命週期裏的 beforeCreate
和 created
,在 Vue 3 裏已被 setup
替代。
setup 語法糖
<script setup>
</script>
- 它只是簡化了以往的
組合API(compositionApi)
的必須返回(return)的寫法,並且有更好的運行時性能。2. 在setup
函數中所有 ES 模塊導出都被認爲是暴露給上下文的值,幷包含在setup()
返回對象中。相對於之前的寫法,使用後,語法也變得更簡單。
ref
ref
是最常用的一個響應式 API,它可以用來定義所有類型的數據,包括 Node 節點和組件。返回一個響應式對象,所有的值都通過.value
屬性獲取。
<template>
<div>{{num}}</div>
</template>
<script setup >
import { ref } from 'vue'
const num = ref(0)
</script>
reactive
返回一個對象的響應式代理。
<template>
<div>{{state.searchInfo.name}}</div>
</template>
<script setup >
import { reactive } from 'vue'
const state = reactive({
searchInfo: {
name: 'Jack',
},
})
</script>
組件自動註冊
在setup
中不再需要用過components
進行註冊,直接引入即可食用。
<template>
<Child />
</template>
<script setup>
import Child from '@/components/Child.vue'
</script>
defineProps
接收父組件傳過來的內容, 可以定義類型和默認值
const props = defineProps({
modelValue: {
type: Array,
default: (() => {[]}),
},
})
defineEmit
子組件向父組件傳遞內容事件
const text = ref(1)
const emit = defineEmits(['update:modelValue'])
emit('update:modelValue', text.value)
defineExpose
向外暴露組件內方法和屬性
傳統的寫法,我們可以在父組件中,通過 ref
實例的方式去訪問子組件的內容,但在 script setup
中,該方法就不能用了,setup
相當於是一個閉包,除了內部的 template
模板,誰都不能訪問內部的數據和方法。
<script setup>
的組件默認不會對外部暴露任何內部聲明的屬性。如果有部分屬性要暴露出去,可以使用defineExpose
// 子組件
const table = ref(null)
defineExpose({
table,
})
// 父組件
<template>
<Child ref="child" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'
let child = ref(null);
onMounted(() => {
console.log(child.value.table); // Child Components
})
</script>
watch
watch(
source, // 必傳,要偵聽的數據源
callback // 必傳,偵聽到變化後要執行的回調函數
// options // 可選,一些偵聽選項
)
watchEffect
<template>
<div>{{num}}</div>
</template>
<script setup >
import { watchEffect, watch, ref } from 'vue'
const num = ref(1)
var id = setInterval(() => {
num.value = num.value + 1
if (num.value === 20) {
clearInterval(id)
id = null
}
}, 1000)
watchEffect(() => {
console.log(1111)
})
watch(() => num.value, () => {
console.log(222, num.value)
})
</script>
watch
和watchEffect
區別:
1、watch 是惰性執行,也就是隻有監聽的值發生變化的時候纔會執行,但是 watchEffect 不同,每次代碼加載 watchEffect 都會執行(忽略 watch 第三個參數的配置,如果修改配置項也可以實現立即執行)
2、watch 需要傳遞監聽的對象,watchEffect 不需要
3、watch 只能監聽響應式數據:ref 定義的屬性和 reactive 定義的對象,如果直接監聽 reactive 定義對象中的屬性是不允許的,除非使用函數轉換一下
4、watchEffect 如果監聽 reactive 定義的對象是不起作用的,只能監聽對象中的屬性。
seSlots() 和 useAttrs()
獲取插槽數據和獲取 attrs 數據,裏面包含了 class、屬性、方法。
// 舊
<script setup>
import { useContext } from 'vue'
const { slots, attrs } = useContext()
</script>
// 新
<script setup>
import { useAttrs, useSlots } from 'vue'
const attrs = useAttrs()
const slots = useSlots()
</script>
其他 Hook Api
-
useCSSModule:CSS Modules 是一種 CSS 的模塊化和組合系統。vue-loader 集成 CSS Modules,可以作爲模擬 scoped CSS。允許在單個文件組件的 setup 中訪問 CSS 模塊。此 api 本人用的比較少,不過多做介紹。
-
useCssVars: 此 api 暫時資料比較少。介紹 v-bind in styles 時提到過。
-
useTransitionState: 此 api 暫時資料比較少。
-
useSSRContext: 此 api 暫時資料比較少。
參考:Vue 官網、小調不喫辣(掘金)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/b7Zqwqbe0FRlntvSSTFCBg