@semki096

Почему после ajax-запроса не получается изменить свойство?

Примерно такой код. Отправляю форму аяксом, появляется иконка загрузки, но последний кусок
...then(function (response) { this.loading = false ...
не отрабатывает, иконка не пропадает. Где я ошибся?

<div id="respond">
...
<textarea v-model="com_text"></textarea>
<button v-on:click="add_comm">Отправить <i  v-show="loading" class="fa fa-spinner fa-spin"></i></button>
</div>
<script>
            var respond = new Vue({
              el: '#respond',
              data: {
                  ...
                  loading: false
              },
              methods: {
                add_comm: function (){
                  this.loading = true;
                  axios.post('/comment', {
                        text: this.com_text,
                      })
                      .then(function (response) {
                          this.loading = false;
                          console.log(response);
                      })
                      .catch(function (error) {
                          console.log(error);
                      });

                }
              }
            });

</script>
  • Вопрос задан
  • 285 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега Vue.js
Контекст потеряли. Так что this в then/catch - это не экземпляр компонента, а window (или undefined - в строгом режиме).

Используйте стрелочную функцию:

.then((response) => {
  this.loading = false;
  console.log(response);
})

Или bind:

.then(function(response) {
  this.loading = false;
  console.log(response);
}.bind(this))

Или сохраняйте контекст в переменную перед запросом:

var that = this;
axios.post('/comment', {
  text: this.com_text,
}).then(function(response) {
  that.loading = false;
  console.log(response);
})

Или сделайте метод асинхронным и вместо then используйте await:

methods: {
  async add_comm() {
    this.loading = true;

    try {
      var response = await axios.post('/comment', {
        text: this.com_text
      });

      console.log(response);
    } catch(error) {
      console.error(error);
    }

    this.loading = false;
  }
}

Или вынесите код коллбеков в отдельные методы (vue самостоятельно привязывает контекст к методам):

methods: {
  add_comm() {
    this.loading = true;

    axios.post('/comment', {
      text: this.com_text
    })
      .then(this.onResponse)
      .catch(this.onError)
      .finally(this.onFinal);
  },
  onResponse(response) {
    console.log(response);
  },
  onError(error) {
    console.error(error);
  },
  onFinal() {
    this.loading = false;
  }
}
Ответ написан
Комментировать
kulakoff
@kulakoff Куратор тега Vue.js
Vue.js developing
...
.then( response => {
     this.loading = false;
     console.log(response);
   })
.catch(error => {
      console.log(error);
  });
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы