深度解析VUE3 Composition API 中的setup 函数

组合式 API:setup()

setup() 钩子是在组件中使用组合式 API 的入口,通常只在以下情况下使用:

  1. 需要在非单文件组件中使用组合式 API 时。
  2. 需要在基于选项式 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)
相关推荐
excel7 小时前
Three.js 材质(Material)详解 —— 区别、原理、场景与示例
前端
掘金安东尼8 小时前
抛弃自定义模态框:原生Dialog的实力
前端·javascript·github
hj5914_前端新手11 小时前
javascript基础- 函数中 this 指向、call、apply、bind
前端·javascript
薛定谔的算法11 小时前
低代码编辑器项目设计与实现:以JSON为核心的数据驱动架构
前端·react.js·前端框架
Hilaku12 小时前
都2025年了,我们还有必要为了兼容性,去写那么多polyfill吗?
前端·javascript·css
yangcode12 小时前
iOS 苹果内购 Storekit 2
前端
LuckySusu12 小时前
【js篇】JavaScript 原型修改 vs 重写:深入理解 constructor的指向问题
前端·javascript
LuckySusu12 小时前
【js篇】如何准确获取对象自身的属性?hasOwnProperty深度解析
前端·javascript
LuckySusu12 小时前
【js篇】深入理解 JavaScript 作用域与作用域链
前端·javascript
LuckySusu12 小时前
【js篇】call() 与 apply()深度对比
前端·javascript