Vue箭头函数与普通函数的正确使用及说明

 更新时间:2025年09月01日 11:05:27   作者:摸鱼一级选手  
文章解析Vue项目中箭头函数与普通函数的this指向差异,指出90%错误源于误用函数类型,提供Vue2/3场景下的使用边界指南,强调需根据是否需要访问Vue实例数据选择函数类型,并给出1个判断标准帮助开发者避免this相关错误

在 Vue 项目中,你是否遇到过这样的场景:

明明写了正确的逻辑,却因为用错函数类型,导致this.msg拿不到值、点击事件不生效?其实,这大多是箭头函数与普通函数的this指向差异在 “搞鬼”。

本文不堆砌理论,而是从实际开发痛点出发,结合 Vue 2/3 的不同场景,带你搞懂两种函数的用法边界,彻底避免这类低级错误。

一、先解决核心困惑:为什么用错函数会出问题?

Vue 中函数报错的根源,90% 都和this指向有关。

箭头函数与普通函数的本质差异,就体现在this的绑定规则上 —— 这是我们判断 “该用哪种函数” 的唯一核心标准。

1. 一张表分清两种函数的关键差异

对比维度普通函数(function)箭头函数(() => {})
this绑定动态:谁调用,this就指向谁静态:定义时继承外层非箭头函数的this
适用场景需要访问 Vue 实例(data/props)时无需绑定实例,需固定this时
能否当构造函数能(new Function())不能(报错)
能否用arguments能(获取所有实参)不能(需用...rest参数)
语法复杂度需写function,代码稍长省略function,简洁(仅匿名)

2. 最关键的this指向对比(附 Vue 场景示例)

  • 普通函数this是 “跟着调用者走” 的。比如 Vue 组件的methods里,函数由组件实例(vm)调用,所以this自然指向vm,能拿到this.data里的内容。
  • 箭头函数this是 “跟着定义环境走” 的。它不会自己绑定this,而是 “抄” 外层非箭头函数的this。如果外层没有非箭头函数,this就会变成window(浏览器)或undefined(严格模式)。
  • 举个直观的例子:
<script>
export default {
  data() {
    return { name: "Vue" };
  },
  created() {
    // 普通函数:由this(组件实例)调用,this指向实例
    const normalFunc = function() {
      console.log(this.name); // 输出"Vue"
    };
    normalFunc.call(this); // 主动绑定this为组件实例

    // 箭头函数:继承外层created的this(组件实例)
    const arrowFunc = () => {
      console.log(this.name); // 输出"Vue"
    };
    arrowFunc(); // 无需绑定,this已固定

    // 注意:如果箭头函数外层是普通函数,this会变
    const outerFunc = function() {
      const innerArrow = () => {
        console.log(this.name); // 这里的this是outerFunc的this(若未绑定则为window)
      };
      innerArrow();
    };
    outerFunc(); // 输出undefined(因为outerFunc的this是window)
  }
};
</script>

二、Vue 2/3 通用场景:哪些地方必须用普通函数?

这些场景的核心需求是 “访问 Vue 实例”,箭头函数会直接导致this失效,哪怕代码能运行,也会埋下隐患。

1.methods中的事件处理函数(绝对不能用箭头函数)

methods里的函数要绑定到模板事件(如@click@input),Vue 会自动把函数的this绑定到组件实例。

如果用箭头函数,this会继承methods定义时的外层环境(通常是window),导致无法访问实例数据。

  • 错误示范(点击按钮无反应,控制台报错):
<template>
  <button @click="changeName">修改名称</button>
  <p>{{ name }}</p>
</template>

<script>
export default {
  data() {
    return { name: "初始名称" };
  },
  methods: {
    // 错误:箭头函数的this不是组件实例
    changeName: () => {
      this.name = "修改后名称"; // 报错:Cannot set property 'name' of undefined
    }
  }
};
</script>
  • 正确示范(点击按钮正常修改):
methods: {
  // 普通函数:this指向组件实例
  changeName() {
    this.name = "修改后名称"; // 正常生效
  }
}

2.computed计算属性(必须用普通函数)

computed需要依赖dataprops计算值,普通函数能确保this指向实例,箭头函数会导致依赖无法读取。

  • 正确写法
computed: {
  fullName() {
    // 普通函数:this能拿到firstName和lastName
    return `${this.firstName} ${this.lastName}`;
  }
}

3.watch监听器(推荐用普通函数)

watch需要在数据变化时执行逻辑(如修改其他数据、调用接口),普通函数的this能直接操作实例,箭头函数会导致逻辑失效。

  • 正确写法
watch: {
  // 监听name变化,更新日志
  name(newVal, oldVal) {
    this.log = `名称从${oldVal}变成${newVal}`; // this指向实例,正常更新
  }
}

4. 生命周期钩子(Vue 2 推荐普通函数,Vue 3setup外同)

Vue 2 的createdmounted等钩子,虽然用箭头函数 “看似能运行”(因为钩子的this是实例,箭头函数会继承),但不符合 Vue 设计规范,且后续维护者容易误解this来源。Vue 3 的Options API(非setup)场景同理。

  • 推荐写法
// Vue 2 / Vue 3 Options API
export default {
  mounted() {
    this.initData(); // 普通函数:this指向实例,调用methods方法
  },
  methods: {
    initData() {
      // 初始化逻辑
    }
  }
};

三、Vue 2/3 通用场景:哪些地方推荐用箭头函数?

这些场景不需要访问 Vue 实例,或需要固定this指向,箭头函数能让代码更简洁,避免手动绑定this的麻烦。

1. 数组方法回调(map/filter/forEach等)

数组方法的回调函数如果用普通函数,this会指向window(非严格模式),需要用that = thisbind(this)绑定;用箭头函数能直接继承外层实例的this,代码更简洁。

  • 对比示例
methods: {
  handleList() {
    const list = [1, 2, 3];

    // 普通函数:需要手动保存this
    const normalResult = list.map(function(item) {
      return item * this.multiplier; // 这里的this是window,需绑定
    }.bind(this)); // 绑定this为组件实例

    // 箭头函数:自动继承外层this(handleList的this是实例)
    const arrowResult = list.map(item => {
      return item * this.multiplier; // 直接使用实例的multiplier
    });

    console.log(arrowResult); // 正确输出:[2,4,6](若multiplier=2)
  },
  data() {
    return { multiplier: 2 };
  }
}

2. 异步请求回调(axios/Promise)

异步操作的回调函数(如接口请求成功 / 失败后),普通函数的this会指向回调的调用者(如axios内部对象),而非 Vue 实例;箭头函数能继承外层实例的this,方便后续操作数据。

  • 正确示例(接口请求后更新数据):
methods: {
  fetchUser() {
    // 外层this是组件实例
    axios.get("/api/user")
      .then(res => {
        // 箭头函数:this指向实例,更新data
        this.userInfo = res.data;
      })
      .catch(err => {
        // 箭头函数:this指向实例,更新错误信息
        this.errorMsg = err.message;
      });
  }
}

3. Vue 3setup函数内(全部用箭头函数)

Vue 3 的Composition API中,setup函数没有thisthis指向undefined),所有函数定义都推荐用箭头函数,避免依赖this导致混乱。

  • 示例
<script setup>
import { ref } from "vue";
const count = ref(0);

// 箭头函数:无需考虑this,直接操作ref
const increment = () => {
  count.value++; // 正确修改ref值
};

// 异步请求示例
const fetchData = () => {
  axios.get("/api/data")
    .then(res => {
      // 直接操作ref或reactive数据
    });
};
</script>

<template>
  <button @click="increment">{{ count }}</button>
</template>

四、避坑指南:90% 开发者会犯的 3 个错误

错误 1:在methods中混用箭头函数和普通函数

有些开发者为了 “简洁”,在methods中部分函数用箭头函数,导致部分功能失效。记住:methods里所有函数都必须用普通函数。

错误 2:Vue 2 生命周期钩子用箭头函数

虽然 Vue 2 中created: () => { this.init() }能运行,但这是 “巧合”—— 如果后续修改外层代码(如把钩子函数嵌套到其他函数中),this会立即失效。

错误 3:Vue 3setup中用普通函数

setup中没有this,普通函数的thisundefined,如果在普通函数中用this,会直接报错。比如:

<script setup>
// 错误:setup中普通函数的this是undefined
const wrongFunc = function() {
  console.log(this.count); // 报错:Cannot read property 'count' of undefined
};
</script>

五、总结:1 个判断标准,搞定所有场景

遇到函数定义时,不用记复杂规则,只需问自己:这个函数需要访问 Vue 实例的data/props/methods吗?

  • 是 → 用普通函数(如methodscomputedwatch);
  • 否 → 用箭头函数(如数组回调、异步回调、Vue 3 setup)。

掌握这个标准,就能彻底避免 Vue 中因函数类型用错导致的this问题,让代码逻辑更清晰、更易维护。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue 2.x 中axios 封装的get 和post方法

    vue 2.x 中axios 封装的get 和post方法

    本文通过实例代码给大家介绍了vue 2.x 中axios 封装的get 和post方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2018-02-02
  • vue3+Ts使用pinia方式(vue-lic搭建项目)

    vue3+Ts使用pinia方式(vue-lic搭建项目)

    文章介绍了如何在Vue 3项目中使用Pinia进行状态管理,主要内容包括安装Pinia、初始化、在main.ts中注册和使用,以及在.vue的setup中使用state,文章还提到getters和actions的使用可以参考官方文档,总结部分表达了作者希望得到大家支持的意愿
    2025-01-01
  • 使用vue引入maptalks地图及聚合效果的实现

    使用vue引入maptalks地图及聚合效果的实现

    这篇文章主要介绍了使用vue引入maptalks地图及聚合效果的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Slots Emit和Props穿透组件封装实现摸鱼加钟

    Slots Emit和Props穿透组件封装实现摸鱼加钟

    这篇文章主要为大家介绍了Slots Emit和Props穿透组件封装实现示例详解,为摸鱼加个钟,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • VUE实现大转盘抽奖

    VUE实现大转盘抽奖

    营运三宝(九宫格、大转盘、老虎机,当然此三宝当然是最基础的营销运营手段),本片文章聊聊大转盘,转盘的实现逻辑应该是营销方案较为简单的一种了,本文将介绍如何实现大转盘抽奖,感兴趣的朋友可以参考下
    2021-05-05
  • 用VueJS写一个Chrome浏览器插件的实现方法

    用VueJS写一个Chrome浏览器插件的实现方法

    这篇文章主要介绍了用VueJS写一个Chrome浏览器插件的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • vue中实现点击变成全屏的多种方法

    vue中实现点击变成全屏的多种方法

    这篇文章主要介绍了vue中实现点击变成全屏的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • vue接入ts基本方法

    vue接入ts基本方法

    这篇文章主要介绍了vue接入ts基本方法,关于ts,也出了很久,下面我们就来简单学习了下ts并且在原有项目上接入基本ts语法,也算是一个初级尝试,简单梳理下基础的接入配置和已经遇到的问题,供需要的小伙伴们参考
    2022-01-01
  • Vue $attrs & inheritAttr实现button禁用效果案例

    Vue $attrs & inheritAttr实现button禁用效果案例

    这篇文章主要介绍了Vue $attrs & inheritAttr实现button禁用效果案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 详解vue如何使用自定义指令

    详解vue如何使用自定义指令

    在Vue的模板语法中,我们学了很多指令,当然除了这些指令,Vue也允许我们自己定义自己的指令,所以本文就来和大家聊聊如何使用自定义指令吧
    2023-10-10

最新评论