setup
setup 函数结束两个参数:props 和 context 一个普通 javascript 对象,暴露了其他可能在 setup 中的值。
export default {
setup (props, context) {
const visible = toRef(props, 'visible')
console.log(visible.value)
const { attrs, slots, emit, expose } = context
}
}
attrs 和 slots 是有状态的对象,它们总是会随组件本身的更新而更新。与 props 不同,attrs 和 slots 的 property 是非响应式的。如果你打算根据 attrs 或 slots 的更改应用副作用,那么应该在 onBeforeUpdate 生命周期钩子中执行此操作。
<script + setup>
script 标签 上添加 setup 属性,会被编译成组件的 setup() 函数的内容。script 标签只有组件被首次引入时执行一次,而 <script + setup> 会在每次组件实例被创建时执行。
defineProps 和 defineEmits
在 <script + setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits,它们具备完整的类型推断,案例如下:
<script setup lang="tsx">
import { useVModel } from '@vueuse/core'
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:visible', 'ok', 'cancel'])
const visibleModel = useVModel(props, 'visible')
const handleClose = () => {
visibleModel.value = false
emit('cancel')
}
</script>
defineExpose
使用 <script + setup> 的组件是默认关闭的,即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script + setup> 中声明的绑定。
<script setup>
const form = ref()
const tableData = ref([])
const validate = () => {
return new Promise((resolve) => {
form.value.validate(valid => {
resolve(valid)
})
})
}
defineExpose({
validate(),
tableData,
})
</script>
useSlots 和 useAttrs
在模板中通过 $slots 和 $attrs 来访问 slots 和 attrs,在 <script + setup> 使用 useSlots 和 useAttrs 来访问它们。
<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
useSlots 和 useAttrs 是真实的运行时函数,它会返回与 setupContext.slots 和 setupContext.attrs 等价的值。
TypeScript 使用 props/emit 声明
props 和 emits 都可以使用传递字面量类型的纯类型语法作为参数给 defineProps 和 defineEmits 来声明,同时 withDefaults 函数提供 props 默认值的方式。
interface Props {
value: string,
placeholder?: string,
}
interface Emits {
(e: 'update:value', val: string): void
}
const props = defineProps<Props>()
// 默认 props 值
const props = withDefault(defineProps<Props>(), {
value: '',
placeholder: '请选择'
})
const emit = defineEmit<Emits>()
defineProps 或 defineEmits 只能要么使用运行时声明,要么使用类型声明,同时使用两种声方法会导致编报错。