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

不是万能函数

相关推荐
霍理迪2 小时前
基础CSS语法
前端·css
粟悟饭&龟波功2 小时前
【GitHub热门项目精选】(2025-12-19)
前端·人工智能·后端·github
流浪法师122 小时前
MyPhishing-Web:AI 驱动的钓鱼邮件检测可视化平台
前端·人工智能
写代码的jiang2 小时前
【无标题】实战:Vue3 + Element Plus 实现树形选择器全量预加载与层级控制
前端·javascript·vue.js
晚烛2 小时前
实战前瞻:构建高可靠、低延迟的 Flutter + OpenHarmony 智慧交通出行平台
前端·javascript·flutter
WHOVENLY3 小时前
【javaScript】- 作用域[[scope]]
前端·javascript
来杯三花豆奶3 小时前
Vue3 Pinia 从入门到精通
前端·javascript·vue.js
syt_10133 小时前
设计模式之-工厂模式
javascript·单例模式·设计模式
卡布叻_星星3 小时前
Docker之Nginx前端部署(Windows版-x86_64(AMD64)-离线)
前端·windows·nginx