Accessing VUE JS's data from Axios

烈酒焚心 提交于 2019-11-30 05:22:37

I can think of these solutions for your problem.

1) You can create a reference to this and use it.

send: function() {
  let self = this
  axios.post(this.api + "orders", this.order).then(function(response) {
    self.message = "Your payment was successful"
  }
}

2) An arrow function will enable you to use this which will point to your Vue instance.

send: function() {
  axios.post(this.api + "orders", this.order).then(response => {
    this.message = "Your payment was successful"
  }
}

3) Use bind to assign an object to this which will be the current Vue instance in your case.

send: function() {
  axios.post(this.api + "orders", this.order).then(function(response) {
    this.message = "Your payment was successful"
  }.bind(this))
}

Your problem is this line

axios.post(this.api+"orders",this.order).then(function(respo‌​nse) {

Examples may use this as you say however, by using a second level of nested function expression, you are accessing a different dynamic this than you think you are.

Basically, send is the method of the Vue object, but since this is not lexically scoped inside of function expressions, only inside of => functions, you have the wrong this reference in the callback you are passing to Promise.prototype.then.

Here is a breakdown:

methods: {
  send: function() {
    // here: `this` technically refers to the `methods` object
    // but Vue lifts it to the entire view object at runtime
    axios.post(this.api + "orders", this.order)
      .then(function(response) {
        // here: `this` refers to the whatever object `the function is called on
        // if it is called as a method or bound explicitly using Function.prototype.bind
        // the Promise instance will not call it on anything
        // nor bind it to anything so `this` will be undefined
        // since you are in a module and modules are implicitly strict mode code.
        this.message = "Your payment was successful";
      });
    }
 }

Try this instead

export default {
  data() {
    return {
    message: "",
    order: {},
  },
  methods: {
    send: function() {
      // here: `this` technically refers to the `methods` object
      // but Vue lifts it to the entire view object at runtime
      axios.post(this.api + "orders", this.order).then(response => {
        // here: this refers to the same object as it does in `send` because
        // `=>` functions capture their outer `this` reference statically.
        this.message = "Your payment was successful";
      });
    }
  }
}

or better yet

export default {
  data() {
    return {
    message: "",
    order: {},
  },
  methods: {
    async send() {
      const response = await axios.post(`${this.api}orders`, this.order);
      this.message = "Your payment was successful";
    }
  }
}

Note in the second example, which uses JavaScript's recently standardized async/await functionality, we have abstracted away the need for a callback entirely so the point becomes moot.

I suggest it here, not because it relates to your question, but rather because it should be the preferred way of writing Promise driven code if you have it available which you do based on your use of other language features. It leads to clearer code when using Promises.

The key point of this answer however, is the scoping of the this reference.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!