VueJS - “this”在通用函数中未定义

Posted

技术标签:

【中文标题】VueJS - “this”在通用函数中未定义【英文标题】:VueJS - "this" is undefined in common function 【发布时间】:2021-05-07 19:11:04 【问题描述】:

我正在尝试提取一个函数以供多个组件使用,但“this”未定义,我不确定如何附加范围的最佳实践方法,因此我的函数知道“this”是什么。我可以将它作为参数传递吗?

组件:-

import goToEvent from "@/common";

export default 
  name: "update",
  methods: 
    goToEvent

常用功能:-

let goToEvent = (event, upcoming=false) => 
    this.$store.dispatch(
        type: 'setEventsDay',
        day: event.start_date
    )

export default goToEvent

当我在组件中调用 goToEvent 时,我得到 TypeError: Cannot read property '$store' of undefined。我该如何避免这种情况?

【问题讨论】:

this 在词法上被解析为箭头函数。你可能需要一个普通的代替。或者参考$store 【参考方案1】:

在这种情况下,我建议将 eventable 定义为 mixin:

const eventable= 
  methods: 
   goToEvent(event, upcoming=false) 
     this.$store.dispatch(
        type: 'setEventsDay',
        day: event.start_date
      )
   
  


export default eventable;

在你的 vue 文件中:

import eventable from "@/eventable";

export default 
  name: "update",
  mixins:[eventable],
....

第二种解决方案

将具有函数的对象导出为嵌套方法,然后将其导入并在methods 选项中传播:

export default 
    goToEvent(event, upcoming=false)
       this.$store.dispatch(
         type: 'setEventsDay',
        day: event.start_date
    )
   
 

然后:

import goToEvent from "@/common";

export default 
  name: "update",
  methods: 
    ...goToEvent,
    otherMethod(),
 

//....

【讨论】:

那么当这个文件有 50 个函数时会发生什么?有没有办法只为 mixin 导入一种方法? 您可以根据需要在多个文件中创建多个 mixin,例如,您可以创建一个名为 eventable.js 的文件,其中包含上面的 mixin mixin 将一个特性组合在一起,并强制代码可重用性【参考方案2】:

你被标记了 Typescript,所以你需要告诉 TS this 实际上有一个值(注意,我不知道 VueJS,我在这里使用通用的 Event 类型,可能有一个更有效和正确的类型!)

第一个选项,手动告诉它有什么 -

let goToEvent = (this:Event, event, upcoming=false) =>

其他选项 - 告诉它它是什么类型 -

let goToEvent: EventHandler = (event, upcoming=false) =>

出于可读性考虑,我个人更喜欢第二种风格。

【讨论】:

箭头函数将始终覆盖 this 的值 - 所以虽然这个答案不正确,但它可能有用 - 请不要投票!!【参考方案3】:

有很多方法可以实现这一点,以下是我喜欢在我的项目中使用的一些方法:

方法一:混入

Mixins 非常适合在组件之间共享一堆方法并且也易于实现,尽管一个很大的缺点是您将无法导入您需要的特定方法。在 mixin 中,this 遵循组件中的规则。

文件:@/mixins/eventable

import  mapActions  from 'vuex'

export default 
  methods: 
    ...mapActions([])
    goToEvent (event, upcoming = false) 
      store.dispatch(
        type: 'setEventsDay',
        day: event.start_date
      )
    
  

在组件中的使用:

import eventable from '@/mixins/eventable'

export default 
  name: 'ComponentName',
  mixins: [eventable],
  methods: 
    componentMethod () 
      this.goToEvent()
    
  
...

方法 2:静态 javascript 文件

在某些情况下,您可能将一组辅助函数保存在一个文件中,并希望能够根据需要进行导入。

在您的情况下,您似乎正在使用存储操作(从调度中假设),因此我将在静态 JS 文件中包括导入和使用存储。

文件:@/static/js/eventable.js

import store from 'path_to_store_file'

const goToEvent = () => 
  store.dispatch('actionName', payload)


export default 
  goToEvent

注意: 虽然这不是完全必要的,但只有将导入的函数声明为组件内的方法,才能将其绑定到组件实例。这将允许您访问 html 部分中的函数。

在组件中的使用:

import  goToEvent  from '@/static/js/eventable.js'

export default 
  name: 'ComponentName',
  methods: 
    // Read note before this code block
    goToEvent,
    componentMethod () 
      // When declared as a method
      this.goToEvent()
      // When not declared, it can still be accessed in the js portion like this
      goToEvent()
    
  
...

【讨论】:

以上是关于VueJS - “this”在通用函数中未定义的主要内容,如果未能解决你的问题,请参考以下文章

“this”在地图函数Reactjs中未定义

为啥在 Vue Composition API 设置函数中未定义“this”?

VueJS 道具在组件中未定义

使用箭头函数时,开发工具中未定义“this”

VueJS <script> 模板 - 小胡子括号中未定义道具

this.state.articles 在 React js 中未定义