首页 > 解决方案 > Vue.js - 在组件方法中使用函数

问题描述

我有一个 vue2 组件,其中一些方法很长,有很多回调,我想更好地结构化它。我尝试按照callbackhell.com遵循指南,但在 vue 方法中事情看起来并不那么容易。

以下是我目前所处位置的示例,它有效,但我对以下内容感到困惑:

  1. 函数提升在这里似乎不起作用,我需要先定义我的函数,然后再运行它们,否则会触发错误。为什么会这样,我在这里错过了什么吗?

  2. 当我像这样定义内部函数时,我失去了绑定到其中的 Vue 组件的“this”。我在函数定义之后修复它.bind(this),它可以工作但看起来相当晦涩。有没有更好的方法来定义方法中的实用函数,同时仍然保持“this”的上下文?

  3. 这通常将函数添加到方法中是 Vue 中的一种好方法吗?我知道我可以直接在methods: {}对象中使它们成为同级方法,这解决了我的大部分问题,但是由于它们只与saveFavourites()方法相关而不与组件中的任何其他内容相关,因此将它们包装在其中对我来说看起来更干净?

非常感谢

methods: {
    saveFavourites() {
        var promptName = function() {
            return this.$swal({
                text: 'Enter name'),
                content: 'input',
                button: {
                    text: 'Save'),
                    closeModal: true,
                },
            })
        }.bind(this);

        var storePlan = function(name) {
            if(!name || (name = name.trim()) === '' ) return;
            axios.post('/api/user-store-daily-favourites', { meals: this.mealIds, name: name })
                .then(response => {
                    if(response.data.status === 'success') {
                        this.$emit('dailyFavouritesUpdated');
                    }
                });
        }.bind(this);

        // running it - if I move this above functions definitions, I get error
        promptName()
            .then( (name) => storePlan(name) );
    },

标签: vue.jsvue-componenthoisting

解决方案


对于问题 1,提升仅适用于函数声明,不适用于函数表达式。相比:

// Expression
var promptName = function() {

至:

// Declaration
function promptName() {

如需进一步阅读,请参阅:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function

对于问题 2,使用bind很好,但您可能会发现使用箭头函数更容易,它保留了周围的this值。

var promptName = () => {
  return this.$swal({
    ...
  })
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

对于问题 3,这似乎是个人喜好问题,但通常我会将它们移到单独的 Vuemethods中。您需要考虑通常的权衡取舍。也许你觉得间接的代价太高了,你宁愿把所有的代码都放在一个地方。没关系。

在这种特定情况下,我建议您查看async/await而不是使用所有这些额外的功能。async但是,请注意,在尝试使用/之前,请确保您充分理解了 Promise,因为/await的大多数问题来自于不了解用于实现它的底层机制。asyncawait

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

/版本看起来像这样asyncawait

async saveFavourites() {
  const name = await this.$swal({
    text: 'Enter name',
    content: 'input',
    button: {
      text: 'Save',
      closeModal: true,
    },
  });

  if(!name || (name = name.trim()) === '' ) return;

  const response = await axios.post('/api/user-store-daily-favourites', {
    meals: this.mealIds,
    name: name
  });

  if(response.data.status === 'success') {
    this.$emit('dailyFavouritesUpdated');
  }
}

推荐阅读