组合式 API:setup()
setup()
钩子是在组件中使用组合式 API 的入口,通常只在以下情况下使用:
- 需要在非单文件组件中使用组合式 API 时。
- 需要在基于选项式 API 的组件中集成基于组合式 API 的代码时。
我们可以使用响应式 API 来声明响应式的状态,在 setup()
函数中返回的对象会暴露给模板和组件实例。其他的选项也可以通过组件实例来获取 setup()
暴露的属性:
xml
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
// 返回值会暴露给模板和其他的选项式 API 钩子
return {
count
}
},
mounted() {
console.log(this.count) // 0
}
}
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
在模板中访问从 setup
返回的 ref 时,它会自动浅层解包,因此你无须再在模板中为它写 .value
。当通过 this
访问时也会同样如此解包。
setup()
自身并不含对组件实例的访问权,即在 setup()
中访问 this
会是 undefined
。你可以在选项式 API 中访问组合式 API 暴露的值,但反过来则不行。
setup()
应该同步地 返回一个对象。唯一可以使用 async setup()
的情况是,该组件是 Suspense 组件的后裔。
源码解析 setup 函数
当应用启动,首次执行渲染函数。会进入 runtime-core/renderer.ts 下的render 函数。当首次渲染,我们主要关注 其中的mountComponent 方法,首先会根据runtime-core/component.ts 下的 createComponentInstance 创建 组件实例对象;然后执行 runtime-core/component.ts 的setupComponent方法根据组件处理数据,如果是一个包含响应式数据的组件会执行同文件下的 setupStatefulComponent ,在这个函数中,我们就会看到 vue 会去尝试读取组件的setup 配置项,如果存在,就执行这个函数。首先在 createSetupContext 中会返回如下的一个setupContext;当Vue 执行setup 函数的时候会传入一个 props, 和 setupContext 2个参数。然后就是返回 setup 方法对实例设置相应的响应式数据,一般情况下返回值可能有2种,一个是返回 一个函数,会被vue 当作组件的render 函数。另一种是返回一个对象,包含了setup 配置的响应式数据,实例方法等,Vue 在处理对象返回值的时候,会将返回的值绑定在组件实例上 的setupState 属性上。后面就是将渲染函数创建一个effect,至此就完成了setup 函数返回 的响应式数据怎么跟组件的渲染函数配置实现双向绑定的了。
arduino
function createSetupContext(instance: ComponentInternalInstance): SetupContext {
return {
attrs: instance.attrs,
slots: instance.slots,
emit: instance.emit
}
}
scss
// 如果是一个对象,会调用 reactivity/res.ts 下的方法
instance.setupState = proxyRefs(setupResult)