如果你的 Vue2 基础还在,学 Vue3 不用 “从头再来”—— 这篇就用你熟悉的 Vue2 选项式 API(data/methods/computed那套)当跳板,通过 “同案例、双写法” 对比,帮你快速找到 Vue3 组合式 API 的对应逻辑,10 分钟搞懂 “原来 Vue3 只是换了种更清爽的写法”。​

我们选一个 Vue2 里最常见的 “计数器 + 用户信息” 案例,先写 Vue2 版本,再写 Vue3 版本,逐行对比差异,看完你会发现:核心逻辑没变,只是代码组织方式更灵活了。​

先回顾:Vue2 选项式 API 怎么写?​

Vue2 里,我们把代码按 “功能” 拆成不同选项(data存数据、methods存方法、computed存计算属性),就像把 “食材” 按类别放进不同盒子,写法很规整,但复杂逻辑会分散在多个选项里。​

先写一个 Vue2 的完整组件(比如叫Vue2Counter.vue),功能包括:​

  1. 计数器(初始值 0,可加可减)​
  2. 用户信息(姓名 + 年龄,点击按钮修改年龄)​
  3. 计算属性(显示 “计数器当前值是奇数还是偶数”)
    <!-- Vue2 选项式 API 写法 -->
    <template>
      <div>
        <h2>Vue2 计数器案例</h2>
        <!-- 用 data 里的变量 -->
        <p>当前计数:{{ count }}</p>
        <!-- 调用 methods 里的方法 -->
        <button @click="addCount">加1</button>
        <button @click="subCount">减1</button>
    
        <hr>
        <!-- 用户信息 -->
        <p>姓名:{{ user.name }}</p>
        <p>年龄:{{ user.age }}</p>
        <button @click="addAge">年龄+1</button>
    
        <hr>
        <!-- 用 computed 里的计算属性 -->
        <p>计数奇偶性:{{ countParity }}</p>
      </div>
    </template>
    
    <script>
    export default {
      // 1. 数据存放在 data 里,必须 return
      data() {
        return {
          count: 0, // 计数器
          user: { // 用户信息(对象)
            name: "张三",
            age: 20
          }
        };
      },
    
      // 2. 方法存放在 methods 里
      methods: {
        addCount() {
          // 用 this 访问 data 里的变量
          this.count += 1;
        },
        subCount() {
          this.count -= 1;
        },
        addAge() {
          this.user.age += 1;
        }
      },
    
      // 3. 计算属性存放在 computed 里
      computed: {
        countParity() {
          // 依赖 count 的变化,自动重新计算
          return this.count % 2 === 0 ? "偶数" : "奇数";
        }
      }
    };
    </script>

Vue2 的核心特点:​

  • 用this访问所有选项里的内容(this.count/this.addCount())​
  • 数据必须放在data()里 return,方法必须放在methods里​
  • 逻辑分散在data/methods/computed等不同选项中​

再对比:Vue3 组合式 API 怎么写?​

Vue3 的组合式 API(搭配script setup语法糖),把 “按功能拆分” 改成了 “按逻辑拆分”—— 比如 “计数器相关的变量和方法” 可以写在一起,“用户信息相关的逻辑” 写在一起,不用再跨data和methods找代码。​

同样的 “计数器 + 用户信息” 案例,用 Vue3 写(Vue3Counter.vue),我们逐部分对应 Vue2 的逻辑:

<!-- Vue3 组合式 API 写法(script setup) -->
<template>
  <!-- 模板部分几乎没变!只是不用关心变量来自哪个选项 -->
  <div>
    <h2>Vue3 计数器案例</h2>
    <p>当前计数:{{ count }}</p>
    <button @click="addCount">加1</button>
    <button @click="subCount">减1</button>

    <hr>
    <p>姓名:{{ user.name }}</p>
    <p>年龄:{{ user.age }}</p>
    <button @click="addAge">年龄+1</button>

    <hr>
    <p>计数奇偶性:{{ countParity }}</p>
  </div>
</template>

<script setup>
// 1. 对应 Vue2 的 data:直接用 let/const 定义变量,不用 return
let count = 0; // 计数器(对应 Vue2 data 里的 count)
const user = { // 用户信息(对应 Vue2 data 里的 user)
  name: "张三",
  age: 20
};

// 2. 对应 Vue2 的 methods:直接定义函数,不用放 methods 里
function addCount() {
  // 不用 this!直接操作变量
  count += 1;
}
function subCount() {
  count -= 1;
}
function addAge() {
  user.age += 1;
}

// 3. 对应 Vue2 的 computed:用 computed 函数定义计算属性
import { computed } from "vue"; // Vue3 需手动引入 computed
const countParity = computed(() => {
  // 依赖 count 变化,自动重新计算(和 Vue2 逻辑一样)
  return count % 2 === 0 ? "偶数" : "奇数";
});
</script>

核心对比:Vue2 选项式 vs Vue3 组合式​

为了让你一眼看清对应关系,我整理了一张对比表,把 Vue2 的核心语法和 Vue3 的写法一一对应:​

功能场景​

Vue2 选项式 API 写法​

Vue3 组合式 API 写法(script setup)​

关键差异​

定义数据(基础类型)​

data() { return { count: 0 } }​

let count = 0​

不用包data(),不用 return​

定义数据(对象 / 数组)​

data() { return { user: { name: '张三' } } }​

const user = { name: '张三' }​

直接定义对象,不用 this 访问​

定义方法​

methods: { addCount() { this.count++ } }​

function addCount() { count++ }​

不用包methods,不用 this​

计算属性​

computed: { parity() { return this.count%2 } }​

import { computed } from 'vue';<br>const parity = computed(() => count%2)​

需手动引入 computed,逻辑更集中​

访问变量 / 方法​

this.count / this.addCount()​

直接用count / addCount()​

彻底告别 this(减少踩坑)​

为什么 Vue3 要改用组合式 API?​

可能你会问:Vue2 的写法挺习惯的,为什么要改?举个例子你就懂了 —— 如果案例更复杂,比如加 “计数器清零”“用户信息重置”“记录计数历史”,Vue2 和 Vue3 的代码组织差异会很明显:​

  • Vue2 问题:“计数器清零” 方法要放methods,“计数历史” 数组要放data,“历史记录过滤” 要放computed—— 相关逻辑被拆在 3 个不同选项里,找代码要跳来跳去。​
  • Vue3 优势:可以把 “计数器相关逻辑” 全部写在一起,“用户信息相关逻辑” 写在一起,比如:
<script setup>
// -------------- 计数器相关逻辑(集中在一起)--------------
let count = 0;
let countHistory = []; // 计数历史
function addCount() { count++; countHistory.push(count); }
function resetCount() { count = 0; countHistory = []; }
const latestHistory = computed(() => countHistory.slice(-3)); // 最近3条历史

// -------------- 用户信息相关逻辑(集中在一起)--------------
const user = { name: '张三', age: 20 };
function resetUser() { user.name = '张三'; user.age = 20; }
</script>

这样不管项目多大,逻辑都像 “模块化积木”,要改计数器就找计数器的代码块,不用跨选项搜索,维护起来更轻松。​

新手过渡避坑:这 3 个点要注意!​

  1. 不要乱用 this:Vue3 的script setup里,this不是 Vue2 里的 “组件实例”,而是undefined(或全局对象),所以千万别写this.count,直接用变量名。​
  2. 需手动引入 API:Vue3 的computed/onMounted等 “全局 API”,要先import才能用(比如import { computed } from 'vue'),Vue2 是直接挂载在this上的。​
  3. 数据响应式(暂时不用慌):目前我们写的count(基础类型)、user(对象)能直接修改并更新页面,是因为 Vue3 对 “普通变量” 做了底层优化 —— 下一篇会专门讲ref和reactive,现在先记住 “简单场景直接写变量就行”。​

小练习:用过渡知识改代码​

试着把 Vue2 的 “TodoList 简单案例” 改成 Vue3 写法,巩固过渡逻辑:​

  • Vue2 写法参考:
    <script>
    export default {
      data() {
        return {
          todoText: "",
          todoList: ["吃饭", "睡觉"]
        };
      },
      methods: {
        addTodo() {
          if (this.todoText) {
            this.todoList.push(this.todoText);
            this.todoText = "";
          }
        }
      }
    };
    </script>
  • Vue3 写法提示:用let todoText = ""、let todoList = ["吃饭", "睡觉"]定义数据,function addTodo()写方法,不用 this。

如果改的时候遇到问题,或者想验证写法对不对,欢迎在评论区留言~ 下一篇我们就深入讲 “响应式 API”,彻底搞懂为什么有些变量要加ref,有些要用reactive!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐