Vue 中 Methods、Computed、watch 的区别:从 Vue2 到 Vue3 的全面解析

在 Vue 开发中,Methods、Computed 和 watch 是处理数据逻辑与交互的核心工具。很多初学者容易混淆三者的用法,尤其是在 Vue2 选项式 API 与 Vue3 组合式 API 的差异下,更需要明确它们的定位与适用场景。本文将从概念、用法(含 Vue2 与 Vue3 对比)、核心区别三个维度展开,结合代码实例帮你彻底理清思路。

一、基础概念与核心特性

在深入代码前,先通过一句话明确三者的核心定位:

  • Methods:普通方法,需主动调用,无缓存,每次调用都会重新执行逻辑;

  • Computed:计算属性,依赖数据变化自动更新,有缓存,仅依赖项改变时才重新计算;

  • watch:监听器,监听指定数据变化,触发自定义回调,可处理异步或复杂逻辑。

二、分场景解析:Vue2 vs Vue3 代码实例

1. Methods:主动触发的 “工具函数”

Methods 是 Vue 实例中定义的普通函数,主要用于处理用户交互(如点击事件)或重复使用的逻辑,必须通过 “调用” 执行(如@click="handleClick"this.handleFn()),且每次调用都会重新执行内部代码,无缓存机制。

Vue2 选项式 API 用法
<template>

 <div>

   <button @click="calcSum">计算1-100的和</button>

   <p>结果:{{ sum }}</p>

 </div>

</template>

<script>

export default {

 data() {

   return {

     sum: 0

   };

 },

 methods: {

   // 定义方法,需通过点击事件触发

   calcSum() {

     this.sum = Array.from({ length: 100 }, (_, i) => i + 1).reduce((a, b) => a + b, 0);

   }

 }

};

</script>
Vue3 组合式 API 用法(setup 语法糖)

Vue3 中无需在methods选项中定义,直接在setup(或语法糖脚本)中声明函数即可,调用方式与 Vue2 一致:

<template>

 <div>

   <button @click="calcSum">计算1-100的和</button>

   <p>结果:{{ sum }}</p>

 </div>

</template>

<script setup>

import { ref } from 'vue';

const sum = ref(0);

// 直接定义函数,作用等同于Vue2的Methods

const calcSum = () => {

 sum.value = Array.from({ length: 100 }, (_, i) => i + 1).reduce((a, b) => a + b, 0);

};

</script>

2. Computed:依赖驱动的 “智能计算”

Computed(计算属性)是基于依赖数据动态生成结果的属性,核心优势是 “缓存”—— 只要依赖的数据源不变化,多次访问 Computed 属性会直接返回缓存结果,避免重复计算,提升性能。此外,Computed 支持 “读写” 两种模式(默认是只读)。

Vue2 选项式 API 用法(只读与可写)
<template>

 <div>

   <!-- 只读:依赖firstName和lastName自动生成全名 -->

   <p>全名:{{ fullName }}</p>

   <!-- 可写:修改fullName时拆分到firstName和lastName -->

   <input v-model="fullName" placeholder="输入全名(如:张三)">

   <p>拆分结果:{{ firstName }} - {{ lastName }}</p>

 </div>

</template>

<script>

export default {

 data() {

   return {

     firstName: '张',

     lastName: '三'

   };

 },

 computed: {

   // 1. 只读计算属性(简写,仅getter)

   // fullName() {

   //   return this.firstName + this.lastName;

   // },

   // 2. 可写计算属性(含getter和setter)

   fullName: {

     get() {

       return this.firstName + this.lastName;

     },

     set(newVal) {

       // 输入“李四”时,拆分出firstName=“李”,lastName=“四”

       const [first, last] = newVal.split('');

       this.firstName = first || '';

       this.lastName = last || '';

     }

   }

 }

};

</script>
Vue3 组合式 API 用法(computed 函数)

Vue3 中需通过computed函数创建计算属性,支持传入 “函数”(只读)或 “对象”(可写),返回的是响应式对象,访问时需通过.value(模板中无需):

<template>

 <div>

   <p>全名:{{ fullName }}</p>

   <input v-model="fullName" placeholder="输入全名(如:张三)">

   <p>拆分结果:{{ firstName }} - {{ lastName }}</p>

 </div>

</template>

<script setup>

import { ref, computed } from 'vue';

const firstName = ref('张');

const lastName = ref('三');

// 1. 只读计算属性(传入函数)

// const fullName = computed(() => firstName.value + lastName.value);

// 2. 可写计算属性(传入对象)

const fullName = computed({

 get() {

   return firstName.value + lastName.value;

 },

 set(newVal) {

   const [first, last] = newVal.split('');

   firstName.value = first || '';

   lastName.value = last || '';

 }

});

</script>

3. watch:数据变化的 “监听者”

watch(监听器)用于监听指定响应式数据的变化,当数据改变时触发回调函数,可处理异步逻辑(如接口请求)或复杂副作用(如操作 DOM)。Vue2 与 Vue3 的 watch 用法差异较大,尤其是 Vue3 新增了watchEffect(自动追踪依赖)。

Vue2 选项式 API 用法(基础监听、深度监听、立即执行)
<template>

 <div>

   <input v-model="username" placeholder="输入用户名">

   <div>用户信息:{{ userInfo.name }} - {{ userInfo.age }}</div>

 </div>

</template>

<script>

export default {

 data() {

   return {

     username: '',

     userInfo: { name: '', age: 0 }

   };

 },

 watch: {

   // 1. 监听基本类型(如username)

   username(newVal, oldVal) {

     console.log('用户名变化:', oldVal, '→', newVal);

     // 模拟异步请求:根据用户名获取用户信息

     setTimeout(() => {

       this.userInfo = { name: newVal, age: 20 + Math.floor(Math.random() * 10) };

     }, 500);

   },

   // 2. 监听对象(需开启深度监听,否则仅对象引用变化才触发)

   userInfo: {

     handler(newVal) {

       console.log('用户信息变化:', newVal);

     },

     deep: true, // 深度监听对象内部属性变化

     immediate: true // 初始渲染时立即执行一次回调

   },

   // 3. 监听对象的单个属性(通过字符串路径)

   'userInfo.name'(newVal) {

     console.log('用户名单独变化:', newVal);

   }

 }

};

</script>
Vue3 组合式 API 用法(watch 函数 + watchEffect)

Vue3 中通过watch函数监听数据,支持监听 “单个数据”“多个数据”“对象(需深度监听)”,同时新增watchEffect(无需指定监听源,自动追踪依赖):

<template>

 <div>

   <input v-model="username" placeholder="输入用户名">

   <div>用户信息:{{ userInfo.name }} - {{ userInfo.age }}</div>

 </div>

</template>

<script setup>

import { ref, reactive, watch, watchEffect } from 'vue';

const username = ref('');

const userInfo = reactive({ name: '', age: 0 });

// 1. 监听基本类型(ref对象)

watch(username, (newVal, oldVal) => {

 console.log('用户名变化:', oldVal, '→', newVal);

 setTimeout(() => {

   userInfo.name = newVal;

   userInfo.age = 20 + Math.floor(Math.random() * 10);

 }, 500);

});

// 2. 监听 reactive 对象(默认深度监听,无需写deep: true)

watch(userInfo, (newVal) => {

 console.log('用户信息变化:', newVal);

}, { immediate: true }); // 立即执行

// 3. 监听对象的单个属性(需用函数返回)

watch(() => userInfo.name, (newVal) => {

 console.log('用户名单独变化:', newVal);

});

// 4. 监听多个数据(数组形式)

watch([username, () => userInfo.age], ([newName, newAge], [oldName, oldAge]) => {

 console.log('用户名或年龄变化:', newName, newAge);

});

// 5. 新增 watchEffect(自动追踪依赖,无需指定监听源)

// 当 username 或 userInfo 变化时,自动执行

watchEffect(() => {

 console.log('watchEffect 触发:', username.value, userInfo.name);

});

</script>

注意:Vue3 中

watch

监听

ref

对象时直接传变量(如

username

),监听

reactive

对象的单个属性时需用 “函数返回”(如

() => userInfo.name

),否则无法正确追踪。

三、三者核心区别对比

通过表格清晰对比 Methods、Computed、watch 的关键差异,帮你快速选择适用场景:

对比维度MethodsComputedwatch
缓存机制无缓存,每次调用重新执行有缓存,依赖变化才更新无缓存,数据变化就触发
触发方式需主动调用(如事件、函数调用)依赖数据变化自动触发监听数据变化自动触发
返回值可返回任意值,也可无返回必须返回一个值(作为属性使用)无返回值,仅执行回调逻辑
适用场景处理用户交互、重复逻辑数据计算(如拼接、过滤)异步操作、复杂副作用(如接口请求、DOM 操作)
依赖追踪无依赖追踪,调用即执行自动追踪依赖数据需手动指定监听源(watchEffect 自动追踪)
Vue3 差异直接定义函数,无选项通过computed函数创建通过watch/watchEffect函数创建,支持多数据监听

四、总结:如何选择?

  1. 当需要处理用户点击、表单提交等交互逻辑,或需要重复调用某段代码时,用Methods

  2. 当需要基于现有数据生成新数据(如拼接姓名、过滤列表),且希望利用缓存提升性能时,用Computed

  3. 当需要在数据变化时执行异步操作(如根据 ID 请求接口)或复杂副作用(如修改 DOM、日志上报)时,用watch

  4. Vue3 中若需自动追踪依赖(无需手动指定监听源),优先用watchEffect

掌握三者的区别与适用场景,能让你的 Vue 代码更高效、更易维护。建议结合实际项目多练习,逐步形成 “按需选择” 的思维习惯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值