news 2026/6/21 3:03:27

都2026年了,还在用Options API?Vue组合式API才是你该掌握的“正确姿势“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
都2026年了,还在用Options API?Vue组合式API才是你该掌握的“正确姿势“

很多人学了Vue 3,却还在用Vue 2的思维写代码。今天咱们聊聊,为什么组合式API不是"可选项",而是你进阶的"必修课"。

先别急,咱们讲个故事

想象一下,你刚入职一家公司,领导让你整理办公桌。

Options API的整理方式是这样的:所有的笔放一个抽屉,所有的本子放一个抽屉,所有的充电线放一个抽屉。

听起来很整齐对吧?但当你要处理"写周报"这件事时,你需要从笔的抽屉拿笔,从本子的抽屉拿本子,从充电线的抽屉拿充电器给电脑充电——你得满办公桌翻。

Composition API的整理方式则是:把"写周报"需要的东西放一起,把"画设计稿"需要的东西放一起。做什么事,拿什么包,干净利落。

这就是Vue组合式API的核心思想——按功能组织代码,而不是按类型分类

听起来简单,但这个理念的转变,足以改变你写Vue代码的方式。

Options API到底"哪里不行了"?

咱们先看一个最经典的计数器组件,用Options API写:

<template> <div> <p>Count: {{ count }}</p> <button @click="increment">+1</button> </div> </template> <script> export default { data() { return { count: 0 } }, methods: { increment() { this.count++ } } } </script>

看起来没毛病对吧?简单、清晰、教科书般的写法。

但问题来了——当你的组件不只是一个计数器,而是同时要处理用户信息、搜索过滤、分页加载、表单校验四五个功能时,你的代码会变成这样:

+------------------+ | data() | ← count、userInfo、searchKey、pageNum、formData 全堆在一起 +------------------+ | methods | ← increment、fetchUser、handleSearch、loadMore、validate 全堆在一起 +------------------+ | computed | ← doubleCount、fullName、filteredList 全堆在一起 +------------------+ | watch | ← 监听count、监听searchKey、监听pageNum 全堆在一起 +------------------+

你发现问题了吗?

"计数器"的逻辑被撕碎了——countdata里,incrementmethods里,doubleCountcomputed里,watch countwatch里。你要理解"计数器"这一个功能,得在四个地方来回跳。

组件小的时候还好,一旦超过200行,维护起来就像在一碗面条里找一根特定的面——这就是Options API的"面条式代码"问题。

组合式API:把散落的拼图重新拼好

同样的计数器,用Composition API重写:

<template> <div> <p>Count: {{ count }}</p> <button @click="increment">+1</button> </div> </template> <script setup> import { ref } from 'vue' const count = ref(0) function increment() { count.value++ } </script>

你会发现几个变化:

第一,没有了this在Options API里,你访问数据要this.count,调用方法要this.increment()。但在组合式API里,一切都是普通的JavaScript变量和函数。没有this指向的困惑,没有"为什么箭头函数里this不对"的经典面试题。

第二,ref是什么?你可以把ref理解为一个"响应式盒子"。普通的JavaScript变量改了值,Vue不知道;但你把值放进ref这个盒子里,Vue就能自动追踪它的变化。访问或修改盒子里的值,需要用.value

第三,<script setup>这是Vue 3推荐的语法糖,它帮你省掉了setup()函数的定义和return语句。在<script setup>里声明的变量和函数,模板可以直接使用。

用一张图来对比两种写法的思维差异:

Options API 的组织方式(按类型分) Composition API 的组织方式(按功能分) ┌─────────────────────┐ ┌─────────────────────┐ │ data: │ │ 🔢 计数器功能: │ │ count │ │ count = ref(0) │ │ searchKey │ │ increment() │ │ userInfo │ │ doubleCount │ ├─────────────────────┤ │ watch(count) │ │ methods: │ ├─────────────────────┤ │ increment │ │ 🔍 搜索功能: │ │ handleSearch │ │ searchKey = ref('')│ │ fetchUser │ │ handleSearch() │ ├─────────────────────┤ │ filteredList │ │ computed: │ ├─────────────────────┤ │ doubleCount │ │ 👤 用户功能: │ │ filteredList │ │ userInfo = ref({}) │ │ fullName │ │ fetchUser() │ ├─────────────────────┤ │ fullName │ │ watch: │ └─────────────────────┘ │ count │ │ searchKey │ └─────────────────────┘

左边是"按抽屉分类",右边是"按事情分类"。哪个更容易维护,一目了然。

进阶三板斧:computed、watch、生命周期

掌握了ref,咱们再学三个核心工具。

第一板斧:computed——自动计算的"公式单元格"

用过Excel吗?你在A1输入数字,B1写个公式=A1*2,A1一变,B1自动变。computed就是Vue里的"公式单元格"。

<script setup> import { ref, computed } from 'vue' const count = ref(0) function increment() { count.value++ } // doubleCount 会随 count 自动更新,不需要你手动维护 const doubleCount = computed(() => count.value * 2) </script>

doubleCount不是一个普通变量,它是一个响应式的计算属性count变了,doubleCount自动变。你不需要写任何"同步逻辑",Vue帮你搞定。

第二板斧:watch——变化的"监控摄像头"

有时候你不只是想"自动算",还想在数据变化时做点什么事——比如发请求、记日志、弹提示。这时候就需要watch

<script setup> import { ref, watch } from 'vue' const count = ref(0) function increment() { count.value++ } watch(count, (newVal, oldVal) => { console.log(`计数从 ${oldVal} 变成了 ${newVal}`) // 实际场景:比如搜索框输入变化时,自动请求接口 // 比如分页页码变化时,自动加载下一页数据 }) </script>

watch的回调会告诉你新值和旧值,让你能精确地响应变化。在实际项目中,watch最常见的用途包括:

  • 监听搜索关键词变化,做防抖请求

  • 监听路由参数变化,重新加载页面数据

  • 监听表单字段变化,实时校验

第三板斧:onMounted——组件"上岗"后的第一件事

组件挂载到页面上之后,你通常需要做一些初始化工作——请求接口、初始化第三方库、设置定时器。这就是onMounted的用武之地。

<script setup> import { ref, onMounted } from 'vue' const message = ref('加载中...') onMounted(() => { // 模拟接口请求 setTimeout(() => { message.value = '数据加载完成 ✅' }, 1000) }) </script> <template> <p>{{ message }}</p> </template>

在Options API里,你得把这段逻辑写在mounted()选项里。但在组合式API中,onMounted就是一个普通函数调用,你可以把它和相关的数据、方法写在一起,不再需要"跳来跳去"。

组合式API的"杀手级特性":Composables

前面讲的都是"怎么在一个组件里用"。但组合式API真正的威力,在于跨组件复用逻辑

在Options API时代,复用逻辑主要靠mixins。但用过的人都知道,mixins有三大坑:

Mixins 的三大坑: ┌──────────────────────────────────────────────┐ │ ❌ 命名冲突:多个mixin可能定义同名属性/方法 │ │ ❌ 来源不明:模板里用的变量,不知道来自哪个mixin │ │ ❌ 隐式依赖:mixin之间可能存在看不见的依赖关系 │ └──────────────────────────────────────────────┘

组合式API的解决方案是Composables(组合式函数)。它本质上就是一个普通的JavaScript函数,返回响应式数据和方法。

来看个实际例子。假设你的项目里有多个组件都需要"计数器"功能:

// useCounter.js import { ref } from'vue' exportfunction useCounter(initialValue = 0) { const count = ref(initialValue) function increment() { count.value++ } function decrement() { count.value-- } function reset() { count.value = initialValue } return { count, increment, decrement, reset } }

在任何组件里使用:

<script setup> import { useCounter } from './useCounter' // 用法一:默认从0开始 const { count, increment, decrement, reset } = useCounter() // 用法二:从100开始计数 const { count: score, increment: addScore } = useCounter(100) </script>

看到了吗?这就是普通的JavaScript函数调用和解构赋值。没有黑魔法,没有隐式注入,每个变量从哪来,一目了然

再来一个更贴近实际开发的例子——封装一个通用的"接口请求"组合函数:

// useFetch.js import { ref } from'vue' export function useFetch(url) { const data = ref(null) const loading = ref(true) const error = ref(null) fetch(url) .then(res => res.json()) .then(json => { data.value = json }) .catch(err => { error.value = err.message }) .finally(() => { loading.value = false }) return { data, loading, error } }

在组件中使用:

<script setup> import { useFetch } from './useFetch' const { data, loading, error } = useFetch('https://api.example.com/users') </script> <template> <div v-if="loading">加载中...</div> <div v-else-if="error">出错了:{{ error }}</div> <ul v-else> <li v-for="user in data" :key="user.id">{{ user.name }}</li> </ul> </template>

三行代码搞定接口请求、加载状态、错误处理。这种复用方式,比mixins不知道高到哪里去了。

一张图看懂:什么时候用Composition API?

你的场景是什么? │ ▼ ┌───────────────┐ 是 ┌──────────────────────┐ │ 简单的小组件? ├────────→│ Options API 完全够用 │ │(< 100行代码)│ │ 不用强行切换 │ └───────┬───────┘ └──────────────────────┘ │ 否 ▼ ┌───────────────┐ 是 ┌──────────────────────┐ │ 需要跨组件 ├────────→│ Composables 是最优解 │ │ 复用逻辑? │ │ 告别 mixins │ └───────┬───────┘ └──────────────────────┘ │ 否 ▼ ┌───────────────┐ 是 ┌──────────────────────┐ │ 组件逻辑复杂? ├────────→│ Composition API │ │(多个关注点) │ │ 按功能分组,更好维护 │ └───────┬───────┘ └──────────────────────┘ │ 否 ▼ ┌──────────────────────────┐ │ 新项目 / 团队协作? │ │ → 推荐 Composition API │ │ 统一代码风格,降低协作成本│ └──────────────────────────┘

写在最后:不是"新的"替代"旧的",而是思维的升级

很多同学一看到"新API"就焦虑:是不是Options API要被废弃了?我之前学的是不是白学了?

大可不必。Vue官方明确表示:Options API不会被移除,两种写法会长期共存

但如果你问我的建议——

如果你是Vue新手,直接从Composition API学起。它更接近原生JavaScript,理解成本反而更低。

如果你是Vue老手,新功能用Composition API写,老代码按需迁移。不必一刀切,但掌握这个能力是进阶的必经之路。

如果你是团队Leader,新项目统一Composition API +<script setup>。代码一致性和可维护性的提升,你的组员会感谢你的。

组合式API的本质不是语法层面的更新,而是代码组织思维的升级。它让你从"按类型分类"转向"按功能分类",让代码像搭积木一样灵活组合。

这一步,迟早要迈。不如,就从今天开始。

如果这篇文章对你有帮助,欢迎点赞 👍让更多人看到,分享 🔗给你身边正在学Vue的朋友,也欢迎在评论区聊聊你从Options API切换到Composition API的体验!

关注「前端达人」,和数万前端开发者一起进阶,每周分享最实用的前端干货 🚀

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 20:44:45

Qwen2.5-VL与Anaconda环境配置指南

Qwen2.5-VL与Anaconda环境配置指南 1. 为什么选择Anaconda来运行Qwen2.5-VL 在开始配置之前&#xff0c;先说说为什么推荐用Anaconda而不是直接用系统Python。Qwen2.5-VL作为一款多模态大模型&#xff0c;依赖的库特别多&#xff0c;而且版本要求很严格——PyTorch、transfor…

作者头像 李华
网站建设 2026/6/16 18:34:07

DeerFlow参数详解:核心智能体的配置选项全解析

DeerFlow参数详解&#xff1a;核心智能体的配置选项全解析 1. 参数配置入门&#xff1a;理解DeerFlow的配置体系 DeerFlow不是那种装完就能随便调的工具&#xff0c;它的多智能体协作特性决定了配置必须既灵活又严谨。当你第一次打开conf.yaml和.env文件时&#xff0c;可能会…

作者头像 李华
网站建设 2026/6/17 0:51:36

lychee-rerank-mm效果惊艳:地图截图与地理坐标描述匹配验证

lychee-rerank-mm效果惊艳&#xff1a;地图截图与地理坐标描述匹配验证 1. 什么是lychee-rerank-mm&#xff1f;轻量级多模态重排序新选择 立知推出的lychee-rerank-mm&#xff0c;是一款专注多模态内容匹配的轻量级重排序模型。它不负责从海量数据里“大海捞针”式地检索&am…

作者头像 李华
网站建设 2026/6/17 4:30:15

GPEN技术局限性分析:当前无法完美处理的几类情况

GPEN技术局限性分析&#xff1a;当前无法完美处理的几类情况 1. GPEN不是万能的人脸修复器 很多人第一次听说GPEN时&#xff0c;会下意识觉得&#xff1a;“既然能修复模糊人脸&#xff0c;那是不是所有烂图都能救回来&#xff1f;” 答案很明确&#xff1a;不能。 GPEN确实…

作者头像 李华