Vue.js - это простой в использовании фреймворк для веб-приложений, который мы можем использовать для разработки интерактивных интерфейсных приложений.

В этой статье мы рассмотрим, как исправить ошибку «это не определено» в приложениях Vue.

Как показать ошибку?

Мы можем получить или не получить сообщение об ошибке «это не определено». Мы можем просто увидеть, что переменные, которые мы ожидали обновить, не обновились.

Как исправить «это не определено»?

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

Стрелочные функции не привязываются к this, который нам нужен для доступа к экземпляру компонента Vue.

Например, если у нас есть следующий код:

index.js :

new Vue({
  el: "#app",
  data: {
    text: "foo"
  },
  methods: {
    toggle: () => {
      this.text = this.text === "foo" ? "bar" : "foo";
    }
  }
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click="toggle">Toggle</button>
      <p>{{text}}</p>
    </div>
    <script src="index.js"></script>
  </body>
</html>

Тогда наш код ничего не сделает, поскольку поле text, возвращаемое из data, не обновляется. Мы можем исправить это, заменив стрелочную функцию обычной функцией следующим образом:

new Vue({
  el: "#app",
  data: {
    text: "foo"
  },
  methods: {
    toggle() {
      this.text = this.text === "foo" ? "bar" : "foo";
    }
  }
});

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

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

Мы можем использовать стрелочные функции как обратные вызовы для других функций, которые мы вызываем внутри методов. Например, если мы хотим отфильтровать что-то в методе, мы можем написать следующий код:

new Vue({
  el: "#app",
  data: {
    name: "",
    names: ["foo", "bar", "baz"]
  },
  computed: {
    filteredNames() {
      if (!this.name) {
        return this.names;
      }
      return this.names.filter(n => this.name === n);
    }
  }
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <input v-model="name" />
      <p v-for="n in filteredNames">{{n}}</p>
    </div>
    <script src="index.js"></script>
  </body>
</html>

В приведенном выше коде у нас есть вычисляемое свойство, которое возвращает отфильтрованные имена в соответствии с тем, что мы вводим во входные данные, которые привязаны к свойству name.

Мы можем использовать стрелочную функцию в обратном вызове filter, потому что мы ссылаемся на this, который уже привязан к функции filteredNames.

Следовательно, у нас уже есть правильное значение this, которое поступает от функции filteredNames. В стрелочной функции значение this берется из того, что установлено, когда вызывается значение this вне стрелочной функции.

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

Получение данных

Для получения данных мы обычно используем HTTP-клиент, который возвращает обещания. Это означает, что мы вызовем функцию then с переданным обратным вызовом. Обратный вызов может быть стрелочной функцией, потому что мы просто хотим получить доступ к this, для которого установлено значение экземпляра Vue.

Например, мы можем написать:

index.js :

new Vue({
  el: "#app",
  data: {
    joke: { value: {} }
  },
  mounted() {
    fetch("https://api.icndb.com/jokes/20")
      .then(res => res.json())
      .then(data => (this.joke = data));
  }
});

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <p>{{joke.value.joke}}</p>
    </div>
    <script src="index.js"></script>
  </body>
</html>

В приведенном выше коде мы использовали стрелочные функции, чтобы установить this.joke в data. Мы можем это сделать, потому что нам нужен this из экземпляра компонента Vue, this.joke ссылается на свойство joke data.

Лексическая область видимости

Стрелочные функции имеют лексическую область видимости, тогда как объем обычных функций определяется во время выполнения. Наличие лексической области видимости - это хорошо, потому что это означает, что область действия этой стрелочной функции зависит от того, как написан код.

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

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

Заключение

Мы можем использовать стрелочные функции до тех пор, пока мы не используем их в методах верхнего уровня внутри самого объекта option компонента Vue. Это связано с тем, что значение this должно быть привязано к экземпляру компонента Vue, чтобы мы могли ссылаться на this. На верхнем уровне мы должны использовать обычные функции для привязки this к экземпляру компонента.