Vue 3 :详解setup 函数
·
什么是 setup 函数?
setup 是 Vue 3 组合式 API 的核心和入口。可以把它理解为组件的"控制中心"——所有组件的逻辑都在这里组织和执行。
执行时机与特点
export default {
setup() {
console.log('setup 执行了')
},
beforeCreate() {
console.log('beforeCreate 执行了')
},
created() {
console.log('created 执行了')
}
}
执行顺序: setup → beforeCreate → created
重要特性: 在 setup 中无法访问 this,因为此时组件实例还没有创建完成。
setup 的参数解析
setup 函数接收两个重要的参数:
1. props - 接收父组件传递的数据
export default {
props: ['title', 'content'],
setup(props) {
// 访问 props
console.log(props.title) // 获取 title
console.log(props.content) // 获取 content
// props 是响应式的,可以使用 watch 监听
watch(() => props.title, (newVal, oldVal) => {
console.log(`title 从 ${oldVal} 变为 ${newVal}`)
})
return {}
}
}
2. context - 组件的上下文信息
context 是一个普通对象,包含三个常用属性:
export default {
setup(props, context) {
// 1. attrs - 获取未在 props 中声明的属性
console.log(context.attrs.class) // 获取 class 属性
console.log(context.attrs.style) // 获取 style 属性
// 2. slots - 访问插槽内容
console.log(context.slots.default) // 默认插槽
console.log(context.slots.header) // 具名插槽
// 3. emit - 触发自定义事件
const handleClick = () => {
context.emit('update', '新数据')
}
return {
handleClick
}
}
}
更常用的解构写法:
setup(props, { attrs, slots, emit }) {
// 直接使用 attrs、slots、emit
}
setup 的返回值
setup 必须返回一个对象,这个对象中的属性和方法可以在模板中直接使用:
import { ref, computed } from 'vue'
export default {
setup() {
// 响应式数据
const count = ref(0)
const name = ref('张三')
// 计算属性
const doubleCount = computed(() => count.value * 2)
// 方法
const increment = () => {
count.value++
}
const reset = () => {
count.value = 0
name.value = '张三'
}
// 返回给模板使用
return {
count,
name,
doubleCount,
increment,
reset
}
}
}
在模板中直接使用:
<template>
<div>
<p>{{ name }}的计数器:{{ count }}</p>
<p>双倍:{{ doubleCount }}</p>
<button @click="increment">+1</button>
<button @click="reset">重置</button>
</div>
</template>
实际开发示例
用户管理组件
<template>
<div>
<input v-model="userForm.name" placeholder="姓名">
<input v-model="userForm.age" placeholder="年龄">
<button @click="addUser" :disabled="!isFormValid">添加用户</button>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }} - {{ user.age }}岁
</li>
</ul>
</div>
</template>
<script>
import { ref, reactive, computed } from 'vue'
export default {
setup() {
// 响应式数据
const users = ref([])
const userForm = reactive({
name: '',
age: ''
})
// 计算属性
const isFormValid = computed(() => {
return userForm.name.trim() && userForm.age
})
// 方法
const addUser = () => {
if (!isFormValid.value) return
users.value.push({
id: Date.now(),
name: userForm.name,
age: userForm.age
})
// 重置表单
userForm.name = ''
userForm.age = ''
}
return {
users,
userForm,
isFormValid,
addUser
}
}
}
</script>
结合生命周期钩子
在 setup 中使用生命周期函数:
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
const data = ref(null)
onMounted(() => {
console.log('组件挂载完成')
// 在这里可以执行初始化操作,比如请求数据
})
onUpdated(() => {
console.log('组件更新了')
})
onUnmounted(() => {
console.log('组件卸载了')
// 在这里可以执行清理操作
})
return {
data
}
}
}
<script setup> 语法糖
Vue 3.2 引入了更简洁的 <script setup> 语法:
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">+1</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 变量和函数自动暴露给模板
const count = ref(0)
const increment = () => {
count.value++
}
// 定义 props 和 emits
defineProps({
title: String
})
defineEmits(['update'])
</script>
总结
setup 函数是 Vue 3 组合式 API 的基石,它:
- 提供了统一的逻辑组织方式
- 接收
props和context参数 - 通过返回值暴露模板需要的内容
更多推荐

所有评论(0)