Доступ к данным 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(response) {
Примеры могут использовать 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
ссылка.