访问 setup 上下文
一、结合单文件组件使用的组合式 API
1.1 useSlots 接收与 slots 属性相同的值
在 <script setup>
使用 slots
的情况应该是相对来说较为罕见的,因为可以在模板中直接通过 $slots
来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlots
两个辅助函数。useSlots
是真实的运行时函数,它的返回与 setupContext.slots
等价。它们同样也能在普通的组合式 API
中使用。
<template>
<div>
</div>
</template>
<script setup lang="ts">
import { useSlots } from "vue"
const slots = useSlots();
console.log(slots);
</script>
1.2 useAttrs 接收与 attrs 属性相同的值
在 <script setup>
使用 attrs
的情况应该是相对来说较为罕见的,因为可以在模板中直接通过 $attrs
来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useAttrs
两个辅助函数。useAttrs
是真实的运行时函数,它的返回与 setupContext.attrs
等价。它们同样也能在普通的组合式 API
中使用。
<template>
<div>
</div>
</template>
<script setup lang="ts">
import { useAttrs } from "vue"
const attrs = useAttrs();
console.log(attrs);
</script>
1.3 defineEmits 接收与 emits 属性相同的值
在 <script setup>
可以使用 defineEmits
接收与 emits
属性相同的值。defineEmits
只能在 <script setup>
中使用的编译器宏。他们不需要导入,且会随着 <script setup>
的处理过程一同被编译掉。
<template>
<div>
<button @click="say">按钮</button>
</div>
</template>
<script setup lang="ts">
import { defineEmits } from 'vue'
const emit = defineEmits(['say'])
const say = () => {
emit('say', '哈哈哈')
}
</script>
1.4 defineExpose 接收与 expose 属性相同的值
在 <script setup>
可以使用 defineExpose
暴露与 expose
相同的属性。defineExpose
只能在 <script setup>
中使用的编译器宏。他们不需要导入,且会随着 <script setup>
的处理过程一同被编译掉。
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
二、基于选项式 API 的组件中集成基于组合式 API
传入 setup
函数的第二个参数是一个 Setup
上下文对象。上下文对象暴露了其他一些在 setup
中可能会用到的值:
export default {
setup(props, context) {
// 透传 Attributes(非响应式的对象,等价于 $attrs)
console.log(context.attrs)
// 插槽(非响应式的对象,等价于 $slots)
console.log(context.slots)
// 触发事件(函数,等价于 $emit)
console.log(context.emit)
// 暴露公共属性(函数)
console.log(context.expose)
}
}
该上下文对象是非响应式的,可以安全地解构为:
export default {
setup(props, { attrs, slots, emit, expose }) {
...
}
}
attrs
和 slots
都是有状态的对象,它们总是会随着组件自身的更新而更新。这意味着你应当避免解构它们,并始终通过 attrs.x
或 slots.x
的形式使用其中的属性。此外还需注意,和 props
不同,attrs
和 slots
的属性都不是响应式的。如果你想要基于 attrs
或 slots
的改变来执行副作用,那么你应该在 onBeforeUpdate
生命周期钩子中编写相关逻辑。