Доступ к данным VUE JS из Axios

У меня есть приложение Vue JS (Vuetify), которое отправляет запрос ajax, и я хотел бы заполнить содержимое div ответом, однако у меня возникают трудности с доступом к данным экземпляра. Все примеры, которые я видел, используют это, чтобы указать на объект данных, но когда я делаю, я получаю эту ошибку

Unable to set property 'message' of undefined or null reference

Приложение довольно простое:

main.js:

import Vue from 'vue'
import App from './App.vue'
import Vuetify from 'vuetify'


Vue.use(Vuetify)

new Vue({
  el: '#app',
  render: h => h(App)
})

App.vue

export default {
  data () {
    return {
    ....
    message: '',
    order: {},
    ...
  },
  methods: {
    send: function() {
      axios.post(this.api+"orders",this.order).then(function(response) {
        this.message = "Your payment was successful";
        ...
      }
   }
 }

this.order доступен без проблем с методом post Axios, однако анонимная функция, которая обрабатывает возвращенное обещание, кажется, имеет проблему с доступом к this.message, в отличие от примеров, которые я видел.

Что я здесь делаю по-другому?

2 ответа

Я могу думать об этих решениях для вашей проблемы.

1) Вы можете создать ссылку на this и использовать это.

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

2) Ан arrow function позволит вам использовать this который будет указывать на ваш экземпляр Vue.

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

3) Использование bind назначить объект this который будет текущим экземпляром Vue в вашем случае.

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

Ваша проблема в этой линии

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

Примеры могут использовать this как вы говорите, однако, используя второй уровень выражения вложенных функций, вы получаете доступ к другому динамическому this чем ты думаешь.

В принципе, send это метод объекта Vue, но так как this не лексически ограничен внутри function выражения, только внутри => функции, вы ошиблись this ссылка в обратном вызове вы переходите к Promise.prototype.then,

Вот разбивка:

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

Попробуйте это вместо

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

или еще лучше

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";
    }
  }
}

Обратите внимание на второй пример, который использует недавно стандартизированный JavaScript async/await функциональность, мы полностью отстранили необходимость в обратном вызове, поэтому вопрос становится спорным.

Я предлагаю это здесь не потому, что это относится к вашему вопросу, а скорее потому, что это должен быть предпочтительный способ написания кода, управляемого Promise, если он у вас есть, что вы делаете на основе использования других языковых функций. Это приводит к более четкому коду при использовании Promises.

Ключевой момент этого ответа, однако, является охват this ссылка.

Другие вопросы по тегам