Vue.js - 在组件方法中使用函数

Vue.js - using functions in component methods

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

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

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

  2. 当我这样定义内部函数时,我丢失了绑定到其中 Vue 组件的 "this"。我在函数定义后通过 .bind(this) 修复它,它可以工作但看起来很晦涩。在保持 "this"?

  3. 的上下文的同时,是否有更好的方法在方法中定义效用函数
  4. 这通常是在 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) );
    },

对于问题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,这似乎是个人喜好问题,但通常我会将它们移至单独的 Vue methods。您需要考虑通常的权衡。也许您觉得间接的代价太高而无法支付,您宁愿将所有代码放在一个地方。没关系。

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

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

async/await 版本看起来像这样:

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');
  }
}