setup 函数完整指南!

你写的是 setup,还是在 setup 里"试错"?🤨

前言:一句话把 setup 定位清楚(非常重要)

setup 是组件实例创建之前执行的"初始化函数"

它负责:

  • 声明响应式状态
  • 组合逻辑
  • 向模板"暴露能力"

理解了这句话,下面 80% 的坑你都会自动避开。

一、setup 的执行时机:为什么 this 在这里是 undefined?😅

1️⃣ setup 什么时候执行?

Vue 3 组件初始化顺序(简化版)👇

json 复制代码
创建组件实例
↓
执行 setup()
↓
解析模板 / render
↓
挂载 DOM
↓
mounted

👉 setup 比 beforeCreate / created 还早

2️⃣ 为什么 setup 里没有 this?

因为此时:

  • 组件实例 还没完全创建
  • data / methods / computed 都不存在
  • Vue 直接把你丢进"初始化沙盒"
ts 复制代码
setup() {
  console.log(this) // undefined
}

✅ 正确心态:

在 setup 里,别找 this,找"变量"

二、setup 的参数解析:props 和 context 到底怎么用?

2️⃣ setup 的函数签名

ts 复制代码
setup(props, context) {}

3️⃣ props:响应式,但"只读"

ts 复制代码
setup(props) {
  console.log(props.title)
}

⚠️ 注意两个重点:

  • props 是 响应式的
  • props 是 只读的
ts 复制代码
props.title = 'xxx' // ❌ 会报警告

👉 如果你需要修改:
要么 emit,要么本地复制

4️⃣ 解构 props 的大坑(非常常见)

ts 复制代码
const { title } = props // ❌ 响应式丢失

✅ 正确写法:

ts 复制代码
import { toRefs } from 'vue'

const { title } = toRefs(props)

5️⃣ context:被很多人忽略的"工具箱"

ts 复制代码
setup(props, { emit, slots, attrs, expose }) {}
emit
ts 复制代码
emit('update', value)
slots
ts 复制代码
slots.default?.()
attrs
  • 非 props 的透传属性
  • class / style / id 都在这
expose(高级)
ts 复制代码
expose({ focus })

👉 控制父组件能通过 ref 访问什么

三、setup 的返回值规则:你"暴露"了什么,模板才能用什么

6️⃣ setup 的返回值 = 模板的作用域

ts 复制代码
setup() {
  const count = ref(0)
  return { count }
}
vue 复制代码
<p>{{ count }}</p>

👉 模板不是全能的,它只能看到你 return 的东西

7️⃣ ref 在模板中为什么不用 .value?

ts 复制代码
const count = ref(0)
vue 复制代码
{{ count }} <!-- 自动解包 -->

👉 模板层会自动 unref

👉 JS 里永远记得 .value

8️⃣ return 的"最佳实践"

✅ 推荐返回:

  • 响应式状态
  • computed
  • 方法
  • 供模板使用的常量

❌ 不推荐返回:

  • 中间变量
  • 临时计算结果
  • 业务工具函数

四、setup 与模板的关系:这是"绑定",不是"引用"

9️⃣ 模板不是 JS,它是"响应式订阅者"

ts 复制代码
const count = ref(0)

模板会自动订阅:

  • count.value 的变化
  • computed 的变化

👉 你不用手动刷新 UI,也不该试图手动刷新

🔟 setup 中声明 ≠ 一定用于模板

ts 复制代码
const internalCache = new Map()

不 return,它就只是逻辑的一部分。

👉 setup = 逻辑层 + 模板桥梁

五、常见错误示例(⚠️重点,很多人就在这翻车)

❌ 错误 1:在 setup 里使用 this

ts 复制代码
setup() {
  this.fetchData() // ❌
}

✅ 正确:

ts 复制代码
const fetchData = () => {}

❌ 错误 2:直接解构 props

ts 复制代码
const { user } = props // ❌

✅ 正确:

ts 复制代码
const { user } = toRefs(props)

❌ 错误 3:忘了 return,模板用不了

ts 复制代码
const count = ref(0)
// 模板访问不到

❌ 错误 4:在 setup 里写副作用,但不清理

ts 复制代码
setInterval(() => {}, 1000) // ❌

✅ 正确:

ts 复制代码
onMounted(() => {})
onUnmounted(() => {})

❌ 错误 5:setup 写成"第二个 data"

ts 复制代码
setup() {
  const a = ref()
  const b = ref()
  const c = ref()
  // 一坨变量,没有结构
}

✅ 正确思路:

👉 逻辑分组 / 抽成组合式函数

六、setup 的"高级正确打开方式"

1️⃣1️⃣ 把 setup 当成"逻辑拼装区"

ts 复制代码
setup() {
  const user = useUser()
  const permission = usePermission()
  const pagination = usePagination()

  return {
    user,
    permission,
    pagination
  }
}

👉 setup 本身应该 很薄

1️⃣2️⃣ <script setup> 的本质(提前说一句)

vue 复制代码
<script setup>
const count = ref(0)
</script>

等价于:

  • 自动 setup
  • 自动 return
  • 自动 expose 给模板

👉 不是新语法,是编译期糖

七、用一句话给 setup 建立"正确心智模型"

setup = 组件的"启动函数 + 依赖注入 + 能力导出"

不是 data

不是 created

不是万能函数

相关推荐
weixin_382395232 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__3 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.3 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~4 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华5 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子7 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅7 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni8 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学9 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端