Accessing VUE JS's data from Axios

前端 未结 2 1946
再見小時候
再見小時候 2020-12-08 17:57

I have a Vue JS (Vuetify) App that makes an ajax request that I would like to populate a div\'s content with the response, however I am having difficulties accessing the ins

相关标签:
2条回答
  • 2020-12-08 18:10

    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.

    0 讨论(0)
  • 2020-12-08 18:24

    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))
    }
    
    0 讨论(0)
提交回复
热议问题