vue3.2正式版已經釋出,script setup文法已經由實驗性質改為了正式文法,可以放心大膽的在項目中用了。
官方文檔:https://v3.cn.vuejs.org/api/sfc-script-setup.html#basic-syntax
相比于正常的composition api文法,script setup文法更加簡練友善,不過它本身隻是個文法糖,最終還是轉換為composition api文法運作。官方文檔純英文且不夠詳細,下面分享一下個人整理的文法使用方式。
- 看這篇文章之前需先提前熟悉vue3新文法變化
- vue版本:v3.2.3
- 使用ts
1、基礎用法
<template>
<Foo :count="count" @click="inc" />
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import Foo from './Foo.vue'
const count = ref(0)
const inc = () => {
count.value++
}
</script>
- 不需要return任何東西,所有定義的變量和方法會自動導出,template模闆可以直接使用
- import引入的元件也會自動導出,模闆裡可以直接引用。
- 引入的元件命名需要首字母大寫。
- 确切的說是:所有的變量方法和import導入都可以在模闆中直接使用。
2、定義props、emit
<template>
<div @click="onClick">{{foo}}</div>
</template>
<script lang="ts" setup>
import { defineProps, defineEmits } from 'vue'
// 定義props屬性
const props = defineProps({
foo: {
type: String,
default: '',
}
})
// 定義emit事件
const emit = defineEmits({
'onSubmit': null,
})
function onClick () {
emit('onSubmit', { val: props.foo })
}
</script>
- 定義的props裡的屬性可以直接在template模闆中使用。
3、自定義指令 directives
<template>
<div v-click-outside />
</template>
<script lang="ts" setup>
import { directive as vClickOutside } from 'v-click-outside'
</script>
- 特殊點就是命名方式,script中使用駝峰命名,template中使用短橫線命名。
4、defineExpose
這個defineExpose是幹什麼的呢,因為script setup預設是不對外界暴露元件執行個體的,是以在其他元件中通過諸如
$refs
和
$parent
都預設無法擷取目前元件執行個體,但是通過defineExpose暴露的可以擷取。(這個設計非常好,對于防止代碼耦合很有用)
- 子元件
:Child.vue
<script lang="ts" setup>
import { ref } from 'vue'
const aaa = 1
const bbb = ref(2)
const ccc = ref(3)
defineExpose({
aaa,
bbb
})
</script>
- 父元件:
<template>
<Child ref="refChild" />
<div @click="onClick">123</div>
</template>
<script lang="ts" setup>
import Child from './Child.vue'
const refChild = ref<any>(null) // 定義同名ref,和template模闆中Child的ref屬性同名,即可代表Child元件執行個體
function onClick () {
console.log(refChild.value) // { aaa: 1, bbb: 2 }
}
</script>
- onClick方法中列印了Child元件執行個體,隻會存在defineExpose暴露出的變量。
5、使用 slots 和 attrs
<script lang="ts" setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
- 通過useSlots和useAttrs來定義,達到類似
和$slots
的效果。$attrs
- 在進階元件封裝中,
主要用于擷取作用域插槽,典型應用場景:base基礎元件的封裝;$slots
主要用于擷取父元件綁定屬性,典型應用場景:第三方元件的二次封裝。具體使用方式比較複雜,這裡不再贅述。$attrs
6、結合普通script
有些setup()之外的配置項在script setup中不适用,可以結合普通script一起使用。
<script lang="ts">
// 普通<script>, 隻會執行一次
runSideEffectOnce()
// 聲明一些額外的配置選項
export default {
name: 'CompName',
inheritAttrs: false,
customOptions: {}
}
</script>
<script lang="ts" setup>
// script setup文法區域
</script>
7、頂層作用域下使用await
在script setup下的頂層作用域下可以直接使用await,
<script setup>
const post = await fetch(`/api/post/1`).then(r => r.json())
</script>
- 這個功能必須結合
使用,目前<suspense>
還在試驗階段,未來應該會成為vue正式功能,官方文檔:https://v3.cn.vuejs.org/guide/migration/suspense.html#%E4%BB%8B%E7%BB%8D<suspense>
8、vscode插件:Volar
script setup文法推薦使用Volar擴充插件配合使用,效果和Vetur類似,但是對script setup文法的相容性更好。
需要注意Volar和Vetur兩個是互斥的,使用Volar時要記得禁用Vetur。