Pull to refresh
833.53
OTUS
Цифровые навыки от ведущих экспертов

Cобытия жизненного цикла компонента

Level of difficultyEasy
Reading time6 min
Views2.1K

Друзья, привет!

Практическое понимание событий жизненного цикла компонентов даёт возможность быстро анализировать и разрабатывать бизнес-задачи. Мы разберём 7 событий жизненного цикла компонентов на примере Composition API в Vue3 фреймворке.

onBeforeMount()

Событие жизненного цикла срабатывает до появления компонента в DOM дереве.

  • Первым из всех событий жизненного цикла имеет доступ к реактивным данным.

  • Компонент создан. Первая фаза рендеринга не началась. Компонента ещё нет в DOM дереве.

Сигнатура метода

onBeforeMount(callback(): void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример: получение данных с сервера

Мы можем запросить данные с сервера сразу после настройки реактивного состояния компонента в <script setup>. Компонент ещё не виден пользователю, но необходимые данные с сервера уже запрошены.

// <script setup>
import {onBeforeMount, ref} from "vue";

const users = ref<{id: number, name: string}[]>([]);

onBeforeMount(async () => {
  const response = await fetch("https://jsonplaceholder.typicode.com/users");
  users.value = await response.json()
})
// template
<ul>
  <li v-for="user of users">{{user.name}}</li>
</ul>

Пример: регистрация событий DOM

Используем onBeforeMount, когда нам необходимо отслеживать в компоненте глобальные события нашего приложения. Например, можно подписаться на событие изменения размера окна.

// <script setup>
import {onBeforeMount} from "vue";
const width = ref(window.innerWidth)

const reszie = () => {
  width.value = window.innerWidth;
}

onBeforeMount(() => {
  window.addEventListener('resize', resize);
})

onMounted()

Событие жизненного цикла срабатывает после появления компонента в DOM дереве.

  • Компонент считается смонтированным, если все дочерние синхронные компоненты смонтированы.

  • Компонент отображается в DOM дереве.

Сигнатура метода

onMounted(callback: () => void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример: инициализация сторонней библиотеки

Для примера возьмем библиотеку отображения графиков Chart.js. Данная библиотека требует на вход ссылку на DOM элемент. Хук onMounted срабатывает после отображения шаблона компонента в DOM дереве. Реактивная ссылка chartRef будет иметь указатель на canvas элемент.

// <script setup>
import {onMounted, ref} from "vue";
const canvasRef = ref<HTMLCanvasElement | null>(null)
const chartRef = shallowRef<ChartJS | null>(null)


onMounted(() => {
  chartRef.value = new ChartJS(canvasRef.value, config as any)
})
// template
<canvas ref="canvasRef"/>

Пример: получение данных из внешнего источника

Если после отображения компонента нам необходимы дополнительные данные с сервера, то используем onMounted() событие.

// <script setup>
import {onMounted, ref} from "vue";

const users = ref<{id: number, name: string}[]>([]);

onMounted(async () => {
  const response = await fetch("http://localhost:3000/users");
  users.value = await response.json()
})
// template
<ul>
  <li v-for="user of users">{{user.name}}</li>
</ul>

Пример: регистрация событий DOM

Используем onMounted, когда нам необходимо отслеживать в компоненте глобальные события нашего приложения. Нам важно, чтобы наш компонент был виден на экране во время создания подписки.

// <script setup>
import {onMounted, ref} from "vue";
const width = ref(window.innerWidth)

const reszie = () => {
  width.value = window.innerWidth;
}

onMounted(() => {
  window.addEventListener('resize', resize)
})

onBeforeUpdate()

Срабатывает до обновления DOM дерева. Используется для взаимодействия с DOM деревом. Безопасно изменять состояние компонента.

Сигнатура метода

onBeforeUpdate(callback: () => void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример: удаление ссылок на компоненты

Если нам необходимо хранить массив ссылок на элементы шаблона нашего компнента, то при изменении кол-ва элементов, необходимо обновить реактивные данные. Если мы используе ref с v-for в шаблоне компонента, то нет гарании, что массив ref будет хранить туже последовательность, что и данные в v-for. Нам нужно самим управлять массивом HTML элементов.

// <script setup>
import {onBeforeUpdate, shallowRef} from "vue";
const liElements = shallowRef<(HTMLLIElement | undefined) []>([])

onBeforeUpdate(() => {
  liElements.value = []
})

const onUpdateRef = (e: any, index: number) => {
  liElements.value[index] = e
}
// template
<li v-for="(user, index) in users"
          :ref="e => onUpdateRef(e, index)"
          :key="user.id"
          tabindex="1"
          @click="onItemClick(user.id)">{{user.name}}</li>

onUpdated()

Callback функция срабатывает после изменения DOM дерева компонентов в соответствии с реактивным сотоянием компонента. Различные изменения состояния объединяются в один цикл рендеринга компонента для отпимизации производительности.

Сигнатура метода

onMounted(callback: () => void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример: получение применённого реактивного стостояния в DOM дереве.

Пользователь нажимает на кнопку, реактивное состояние компонента изменяется и применяется к DOM. Callback в onUpdated методе содержит одинаковые данные как в DOM, так и в реактивном состоянии.

// <script setup>
import {onUpdated, ref} from "vue";

const count = ref(0)
const divRef = ref<HTMLDivElement | null>(null)

onUpdated(() => {
  const divCountValue = parseInt(divRef.value.innerHTML)
  // divCountValue === count => true
  console.log(divCountValue === count.value)
})
// template
  <div ref="divRef">{{count}}</div>
  <button @click="count++">Count</button>

onBeforeUnmounted()

Вызов происход до момента удаления компонента. Реактивные состояния компонента активны. Расположить логику, которая удалит события или подчистит использование памяти, хорошая мысль

Сигнатура метода

onBeforeUnmounted(callback: () => void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример: удаление таймеров созданных в компоненте

Регистрация событий, таймеров происходит в onBeforeMount или onMounted в зависимости от целей задачи. Очистка зарегестрированных обработчиков выполняется в onBeforeUnmount.

// <script setup>
let intervalId;

onMounted(() => {
  intervalId = setInterval(() => {
    // logic here
  },1000)
})

onBeforeUnmount(() => {
  clearInterval(intervalId)
})

onUnmounted()

Компонент уничтожен. Все реактивные состояния остановлены. Мы можем взаимодействовать с созданными подписками таймеров, DOM или подключением к серверу.

Сигнатура метода

onUnmounted(callback: () => void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример использования

Удаление обработчика события изменения окна.

// <script setup>
import {onMounted, onUnmounted, ref} from "vue";
const size = ref({width: window.innerWidth, height: window.innerHeight})

const resize = () => {
  size.value.width = window.innerWidth
  size.value.height = window.innerHeight
}

onMounted(() => {
  window.addEventListener('resize', resize)
})

onUnmounted(() => {
  window.removeEventListener('resize', resize)
})

onErrorCaptured()

Метод предоставляет возможность перехватывать ошибки в компоненте. Ошибки кода в <script setup>, рендеринга, обработчиков событий, функций жизненного цикла компонента, наблюдателей, директив и переходов.

Сигнатура метода

onBeforeUnmounted(callback: () => void): void

Выполнение функции callback синхронное. Можно выполнять асинхронный код в callback функции. Vue фреймворк не будет ждать завершение исполнения асинхронного кода.

Пример: отображение ошибки из дочернего компонента

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

// <script setup>
const error = ref<string | undefined>()

onErrorCaptured((err, instance, info) =>{
  error.value = err.message;
})
// template
  <ErrorComponent v-if="!error"/>
  <div v-if="error">Error: {{error}}</div>

Резюме

Понимание событий жизненного цикла компонента упрощает реализацию бизнес-задач.

Lifecycle Hook

Когда

Для чего

onBeforeMount

до вставки в DOM

регистрация глобального события, получение данных из внешнего источника

onMounted

после вставки в DOM

регистрация глобального события, получить дополнительные данные из внешнего источника, встроить внешние библиотекти

onBeforeUpdate

до обновления DOM

получить состояние DOM до обновления

onUpdated

после обновления DOM

получить обновлённое состояние DOM

onBeforeUnmount

до уничтожения компонента

удалить глобальные события с возможностью использования реактивных данных, разорвать соединения с внешними источниками

onUnmounted

компонент уничтожен

удалить глобальные события, разорвать соединения с внешними источниками

onErrorCaptured

во время возникновения ошибки на этапе жизни компонента

поймать ошибки компонента

Ссылка на исходный код.

Статья подготовлена в преддверии старта курса Vue.js Developer. Узнать подробнее о курсе.

Tags:
Hubs:
Total votes 13: ↑11 and ↓2+15
Comments7

Articles

Information

Website
otus.ru
Registered
Founded
Employees
101–200 employees
Location
Россия
Representative
OTUS