
Vue3setup详解一、setup 是什么二、基本语法写法一选项式写法传统写法二script setup 语法糖推荐 ⭐⭐⭐⭐⭐三、setup 的两个参数3.1 props — 父组件传参3.2 context — 上下文四、setup 能做什么4.1 声明响应式数据4.2 计算属性 computed4.3 侦听器 watch4.4 生命周期钩子4.5 方法定义五、逻辑复用组合函数 useXxx六、setup 的注意事项七、完整示例一、setup 是什么setup是 Vue 3 引入的组合式 APIComposition API核心入口是一个在组件实例创建之前执行的函数用于替代 Vue 2 中的beforeCreate和created钩子。执行顺序 setup() → beforeCreate() → created() → ...其他生命周期⚠️ 关键点setup 中this是undefined不能用this访问组件实例二、基本语法写法一选项式写法传统templatedivp{{count}}/pbutton clickincrement1/button/div/templatescriptimport{ref}fromvueexportdefault{// ✅ Vue3 新增选项setup(){constcountref(0)constincrement(){count.value}// 返回值暴露给模板return{count,increment}}}/script写法二script setup语法糖推荐 ⭐⭐⭐⭐⭐templatedivp{{count}}/pbutton clickincrement1/button/div/templatescript setupimport{ref}fromvue// ✅ 不需要 return自动暴露给模板constcountref(0)constincrement(){count.value}/script 推荐用script setup更简洁不用写return三、setup 的两个参数setup(props,context){// props → 父组件传来的数据响应式// context → 上下文对象 { attrs, slots, emit }}3.1 props — 父组件传参exportdefault{props:{title:String,count:{type:Number,default:0}},setup(props){console.log(props.title)// ✅ 直接访问console.log(props.count)// ⚠️ 不要解构会丢失响应性// const { title } props ❌// ✅ 要解构用 toRefsimport{toRefs}fromvueconst{title}toRefs(props)// title.value}}3.2 context — 上下文setup(props,{attrs,slots,emit}){// attrs → 未在 props 中声明的属性// slots → 插槽内容// emit → 触发父组件事件constsendEvent(){emit(custom-event,hello)// 通知父组件}return{sendEvent}}四、setup 能做什么4.1 声明响应式数据API用途示例ref()单个值基本类型/对象const count ref(0)reactive()对象/数组const state reactive({ name: Tom })import{ref,reactive}fromvuesetup(){// refJS 中用 .value模板中自动解包不用 .valueconstcountref(0)// reactive直接访问属性constuserreactive({name:张三,age:20})return{count,user}}4.2 计算属性 computedimport{ref,computed}fromvuesetup(){constcountref(0)constdoublecomputed(()count.value*2)return{count,double}}4.3 侦听器 watchimport{ref,watch}fromvuesetup(){constcountref(0)watch(count,(newVal,oldVal){console.log(从${oldVal}变为${newVal})})return{count}}4.4 生命周期钩子import{onMounted,onUpdated,onUnmounted,onBeforeMount,onBeforeUpdate}fromvuesetup(){onMounted((){console.log(组件挂载完成)})onUnmounted((){console.log(组件销毁)// 清除定时器等操作})return{}}4.5 方法定义setup(){constcountref(0)// 普通函数constincrement(){count.value}// 或返回响应式方法constreset(){count.value0}return{count,increment,reset}}五、逻辑复用组合函数 useXxx这是 setup 最大的优势把逻辑抽成独立函数// useCounter.jsimport{ref}fromvueexportfunctionuseCounter(initialValue0){constcountref(initialValue)constincrement()count.valueconstdecrement()count.value--return{count,increment,decrement}}!--组件中使用--script setupimport{useCounter}from./useCounterconst{count,increment,decrement}useCounter(10)/scripttemplatep{{count}}/pbutton clickincrement1/buttonbutton clickdecrement-1/button/template 多个组件可以复用同一个useXxx代码不重复六、setup 的注意事项规则说明❌ 不能用thissetup 中this是undefined✅ 返回值暴露给模板return { xxx }或script setup自动暴露⚠️ 不要解构 props会丢失响应性用toRefs()⚠️ 不要解构 context.attrs/slots它们是非响应式的 异步支持可以返回 Promise配合Suspense使用 Vue2 选项可访问 setup但 setup 不能访问 Vue2 的 data/methods七、完整示例templatedivclassuser-cardh2{{user.name}}-{{user.age}}岁/h2p双倍年龄{{doubleAge}}/pbutton clickincrement年龄1/buttonbutton clickchangeName改名/buttonslot/slot/div/templatescript setupimport{ref,reactive,computed,onMounted,watch}fromvue// ✅ 接收 propsconstpropsdefineProps({initialName:{type:String,default:未知}})// ✅ 响应式数据constuserreactive({name:props.initialName,age:18})// ✅ 计算属性constdoubleAgecomputed(()user.age*2)// ✅ 方法constincrement(){user.age}constchangeName(){user.name新名字}// ✅ 侦听watch(()user.age,(newAge){console.log(年龄变为${newAge})})// ✅ 生命周期onMounted((){console.log(组件挂载了)})// ✅ 触发事件给父组件constemitdefineEmits([age-changed])/scriptstyle scoped.user-card{padding:20px;border:1px solid ccc;border-radius:8px;}/style 一图总结setup() ├── 参数props父传子数据 contextattrs/slots/emit ├── 声明ref / reactive响应式数据 ├── 计算computed派生值 ├── 侦听watch数据变化 ├── 生命周期onMounted / onUnmounted 等 ├── ️ 方法普通函数 / 箭头函数 ├── 返回暴露给模板使用 └── 复用抽成 useXxx 组合函数 总结一句话setup 就是 Vue 3 的大脑把组件的数据、方法、生命周期全部组织在一个函数里比 Vue 2 更灵活、更好复用