Vue 3 组合式 API(Composition API)是 Vue 3 的核心特性之一,它解决了选项式 API 在复杂组件中"逻辑分散、复用困难"的问题。本文通过实际示例带你快速上手。
一、为什么需要组合式 API
在选项式 API 中,一个功能的代码会被拆散到 data、methods、computed、watch 中。组件一旦复杂,想要定位某个功能的所有代码就要在多个选项之间来回跳转。组合式 API 允许我们按"功能"而不是按"选项类型"组织代码。
二、响应式核心:ref 与 reactive
<script setup>
import { ref, reactive } from 'vue'
// ref 适合基本类型
const count = ref(0)
const username = ref('guest')
// reactive 适合对象
const user = reactive({
name: '张三',
age: 25,
})
// 模板中自动解包,无需 .value
// 脚本中操作需要 .value
count.value++
function increment() {
count.value++
}
</script>
记住一条经验:基本类型用 ref,嵌套对象用 reactive。不过现在也推荐统一用 ref,配合 toRefs 或解构使用更灵活。
三、computed 计算属性
import { ref, computed } from 'vue'
const price = ref(100)
const quantity = ref(2)
// 计算属性有缓存,只有依赖变化时才重算
const total = computed(() => price.value * quantity.value)
// 计算属性默认只读
// 可通过 get/set 实现可写
const totalEditable = computed({
get: () => price.value * quantity.value,
set: (val) => { price.value = val / quantity.value },
})
四、watch 侦听器
import { ref, watch } from 'vue'
const keyword = ref('')
// 侦听单个源
watch(keyword, (newVal, oldVal) => {
console.log('搜索词变化:', oldVal, '→', newVal)
})
// 侦听多个源
watch([keyword, page], ([k, p]) => {
console.log('条件变化', k, p)
})
// 深度侦听对象
watch(user, (val) => { ... }, { deep: true })
// 立即执行一次
watch(keyword, fn, { immediate: true })
使用 watchEffect 可以自动收集依赖,不需要显式指定侦听的源,适合"副作用跟随状态"的场景。
五、组合式函数:逻辑复用
这是组合式 API 最大的优势。把可复用的逻辑抽成函数:
// usePagination.js
import { ref, computed } from 'vue'
export function usePagination(pageSize = 10) {
const page = ref(1)
const total = ref(0)
const totalPages = computed(() => Math.ceil(total.value / pageSize))
const canPrev = computed(() => page.value > 1)
const canNext = computed(() => page.value < totalPages.value)
function prev() { if (canPrev.value) page.value-- }
function next() { if (canNext.value) page.value++ }
function reset() { page.value = 1 }
return { page, total, totalPages, canPrev, canNext, prev, next, reset }
}
在任意组件中使用:
<script setup>
import { usePagination } from './usePagination'
const { page, total, totalPages, prev, next } = usePagination(20)
// 组件只需要关心业务逻辑
function loadData() {
// 使用 page.value 请求接口
}
</script>
六、script setup 语法糖
Vue 3.2+ 推荐使用 <script setup>:
- 顶层声明自动暴露给模板,无需 return
- import 的组件直接可用
- 支持
defineProps/defineEmits声明属性与事件 - 代码更简洁,编译期有性能优化
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({ title: String, items: Array })
const emit = defineEmits(['select'])
function handleClick(item) {
emit('select', item)
}
</script>
小结
组合式 API 的学习曲线平缓,一旦上手就能体会到代码组织与复用的乐趣。建议新项目直接用 <script setup> + 组合式函数,从第一天就保持组件的清晰与可维护。