setup()
此页面记录了setup
组件选项的使用。如果您将 Composition API 与单文件组件一起使用,建议使用<script setup>
更简洁。
在以下情况下,该setup()
钩子用作组件中组合 API 使用的入口点:
- 在没有构建步骤的情况下使用 Composition API;
- 在 Options API 组件中与基于 Composition-API 的代码集成。
基本用法
我们可以使用响应式 API,声明反应状态,并通过从setup()
返回对象的属性也将在组件实例上可用(如果使用其他选项):
<script> import { ref } from 'vue' export default { setup() { const count =ref (0) // expose to template and other options API hooks return { count } }, mounted() { console.log(this.count) // 0 } } </script> <template> <button@click ="count++">{{ count }}</button> </template>
请注意,在模板中访问时,从返回的refs,setup
会自动浅展开.value,因此您在访问它们时不需要使用。当在组件上访问时,它们也以相同的方式展开this
。
setup()
本身无权访问组件实例。在setup()内, this
的值不存在。您可以从 Options API 访问 Composition-API 公开的值,但反之则不行。
访问 props
setup()
函数中的第一个参数是props,它是响应式的,并且会在传入新的props时更新。
export default { props: { title: String }, setup(props) { console.log(props.title) } }
注意:如果您对props对象进行解构,则被解构的变量将失去反应性。因此建议始终以props.xxx形式访问。
如果您确实需要解构props,或者需要将props传递给外部函数同时保持反应性,您可以使用toRefs()
和toRef()
实用程序 API 执行此操作:
import { toRefs } from 'vue' export default {setup (props) { // turn `props` into an object of refs, then destructure const { title } = toRefs(props) // `title` is a ref that tracks `props.title` console.log(title.value) // OR, turn a single property on `props` into a ref const title = toRef(props, 'title') } }
设置上下文 context
传递给setup()
函数的第二个参数是一个设置上下文context对象。上下文对象暴露了其他可能在setup()
内部有用的值:
export default { setup(props, context) { // Attributes (Non-reactive object, equivalent to $attrs) console.log(context.attrs) // Slots (Non-reactive object, equivalent to $slots) console.log(context.slots) // Emit events (Function, equivalent to $emit) console.log(context.emit) // Expose public properties (Function) console.log(context.expose) } }
上下文对象不是响应式的,可以安全地解构:
export default { setup(props, { attrs, slots, emit, expose }) { ... } }
attrs、slots是在组件本身更新时,始终更新的有状态对象。这意味着您应该避免对它们进行解构,并始终将属性引用为attrs.x或slots.x。
另请注意,与props不同,attrs、slots属性不是响应式的。如果您打算根据对其的更改应用副作用,则应在生命周期onBeforeUpdate
挂钩中执行此操作。
暴露公共属性
默认状态下,本组件实例的属性方法,不能被父组件访问。expose()
函数,可用于显式暴露:
export default { setup(props, { expose }) { // make the instance "closed" // i.e. do not expose anything to the parent expose() const publicCount = ref(0) const privateCount = ref(0) // selectively expose local state expose({ count: publicCount }) } }
与渲染函数一起使用
setup()
还可以返回一个渲染函数,该函数可以直接使用在同一范围内声明的反应状态:
import { h, ref } from 'vue' export default { setup() { const count = ref(0) return () => h('div', count.value) } }
返回一个渲染函数,可以防止我们返回其他任何东西。在内部这应该不是问题,但是如果我们想通过模板引用将此组件的方法公开给父组件,则可能会出现问题。
我们可以通过调用expose()
来解决这个问题:
import { h, ref } from 'vue' export default { setup(props, { expose }) { const count = ref(0) constincrement = () => ++count.value expose({increment }) return () => h('div', count.value) } }
然后,该