vue.js 回调方法中无法修改组件变量

Ash*_*269 1 javascript closures callback amazon-web-services vue.js

Login.vue在 vue.js 中定义了一个组件,让我可以通过 AWS Cognito 将用户登录到我的应用程序。我使用该___.authenticateUser()方法登录用户并开始与 Cognito 的会话。下面是这样做的实际代码:

export default {
  name : 'Login',
  data: function() {
    return {
      errorMessageHidden: true,
      formHidden: false,
      errorMessage: '',
      email: '',
      password: ''
    }
  },
  methods: {
    showValuesToMe: function() {
      console.log(this.errorMessageHidden)
    },
    handleLogin: function() {
      const data = {
        Username: this.email,
        Pool: userPool
      }

      const cognitoUser =  new CognitoUser(data);

      const authenticationData = {
        Username : this.email,
        Password : this.password,
      };

      function showErrorMessage(err) {
        this.errorMessageHidden = false;
        this.errorMessage = err.message;
        console.log("The method got called... errorMessageHidden = " + this.errorMessageHidden);
      }

      const authenticationDetails = new AuthenticationDetails(authenticationData)

      cognitoUser.authenticateUser(authenticationDetails, {
        callback: showErrorMessage,
        onSuccess: function(result) {
          console.log('access token ' + result.getAccessToken().getJwtToken());
        },
        onFailure: function(err) {
          this.callback(err);
        }
      });
    },

    hideErorrMessage: function() {
      this.errorMessageHidden = true;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是,在handleLogin()组件的函数内部,何时___.authenticateUser()调用 Cognito SDK 调用onSuccess()onFailure()取决于来自 AWS 的身份验证结果。

onFailure()我尝试修改的时候errorMessageHiddenerrorMessage他们不能!这onFailure()是因为该方法是一个回调方法和一个闭包。

为了访问/修改这些值,我function showErrorMessage(err) {...}在闭包的父级范围内定义了。现在我可以访问中定义的值,data但仍然无法修改它们。

谁能弄清楚我如何更改值以进行更改并在浏览器中显示错误。

小智 5

您的问题是因为您function在回调函数中使用而不是箭头函数。当您使用function新的作用域创建一个函数时,this它不再是您的 Vue 组件。

你想这样做:

handleLogin: function() {
      const data = {
        Username: this.email,
        Pool: userPool
      }

      const cognitoUser =  new CognitoUser(data);

      const authenticationData = {
        Username : this.email,
        Password : this.password,
      };

      const showErrorMessage = err => {
        this.errorMessageHidden = false;
        this.errorMessage = err.message;
        console.log("The method got called... errorMessageHidden = " + this.errorMessageHidden);
      }

      const authenticationDetails = new AuthenticationDetails(authenticationData)

      cognitoUser.authenticateUser(authenticationDetails, {
        callback: showErrorMessage,
        onSuccess: result => {
          console.log('access token ' + result.getAccessToken().getJwtToken());
        },
        onFailure: err => {
          this.callback(err);
        }
      });
    }
Run Code Online (Sandbox Code Playgroud)

使用箭头函数,您将维护调用它的函数的作用域,因此如果您在 Vue 方法内部并使用箭头函数,则箭头函数内部this仍将是 Vue 组件。

请注意,您不能将箭头函数用作methods对象的直接属性。那是因为 Vue 需要调用 Vue 组件绑定到的函数this,这是箭头函数无法做到的。但除此之外,您可能希望开始使用箭头函数,这是我最喜欢的 ES5 特性之一。