【问题标题】:Accessing VUE JS's data from Axios从 Axios 访问 VUE JS 的数据
【发布时间】:2017-12-26 06:51:38
【问题描述】:

我有一个 Vue JS (Vuetify) 应用程序,它发出一个 ajax 请求,我想用响应填充 div 的内容,但是我在访问实例的 数据 时遇到了困难。我见过的所有示例都使用 this 指向数据对象,但是当我这样做时,我得到了这个错误

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

应用程序非常简单:

ma​​in.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 可以通过 Axios 的 post 方法毫无问题地访问,但是处理返回的承诺的匿名函数似乎在访问 this 时出现问题。消息,与我看到的例子相反。

我在这里做的不同是什么?

【问题讨论】:

  • 你的问题是这行axios.post(this.api+"orders",this.order).then(function(response) {。示例可能会使用 this,但是通过使用第二个嵌套的 function 表达式,您访问的动态 this 与您认为的不同。将=> 函数传递给.then。基本上,.send 是 vue 对象的方法,但由于 this 不是 function 表达式内部的词法范围,仅在 => 函数内部,你的回调中有错误的 this 引用。
  • Axios can't set data的可能重复

标签: javascript vuejs2 axios lexical-closures vuetify.js


【解决方案1】:

我可以为您的问题想出这些解决方案。

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

【讨论】:

  • 谢谢,问题已解决,并推荐此答案,因为易于理解
  • @DarkteK 酷,不过我建议在这种情况下使用箭头函数。
  • 惊人的答案。到 2021 年仍能挽救生命
【解决方案2】:

你的问题是这一行

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

如您所说,示例可能使用this,但是,通过使用第二级嵌套函数表达式,您访问的动态this 与您想象的不同。

基本上,send 是 Vue 对象的方法,但由于 thisfunction 表达式内部没有词法范围,仅在 => 函数内部,你在回调您传递给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 参考的范围。

【讨论】:

  • 谢谢,有帮助
  • Aluan Haddad 你会如何错误处理异步等待版本?
  • async/await 允许您在异步代码中使用标准控制结构,以便处理 try { await f() } catch (e) {} 的错误。
猜你喜欢
  • 2019-05-12
  • 2019-05-17
  • 2020-05-28
  • 1970-01-01
  • 2021-01-04
  • 2019-11-05
  • 2021-05-08
  • 2017-06-28
  • 2017-12-27
相关资源
最近更新 更多