Рад приветствовать вас снова, друзья-энтузиасты Vue.js! Сегодня мы продолжим наш увлекательный экскурс по новейшим фичам и улучшениям, которые ожидают нас в Vue 3!
В нашей предыдущей статье "Миграция с Vue 2 на Vue 3: Устаревшие и Обновленные Фичи" мы рассмотрели основные обновления и изменения в Vue 3, которые послужили основой для плавного перехода с Vue 2 на Vue 3.
В этой статье мы сделаем следующий шаг — погрузимся с головой в захватывающий мир новых возможностей Vue 3!
Эта поистине революционная версия горячо любимого всеми нами JavaScript-фреймворка стремится стать переосмыслением подхода к созданию веб-приложений, предлагая множество улучшений, оптимизаций и инструментов, призванных сделать процесс разработки более плавным, быстрым и приятным.
Без лишних отлагательства приступим к делу!
Composition API
Первая в нашем обзоре и наиболее интересная фича — это Composition API.
Согласно документации Vue.js, Composition API — это набор API, который позволяет нам создавать компоненты Vue, используя импортированные функции вместо объявления опций. Это сборная солянка, которая охватывает следующие API:
Reactivity API, например, ref() и reactive(), позволяющие напрямую создавать реактивное состояние (reactive state), вычисляемое состояние (computed state) и наблюдатели (watchers).
Хуки жизненного цикла (Lifecycle Hooks), например, onMounted() и onUnmounted(), позволяющие программно подвязываться к жизненному циклу компонента.
Внедрение зависимостей (Dependency Injection), т.е. provide() и inject(), которые позволяют нам использовать систему внедрения зависимостей Vue вместе с Reactivity API.
С помощью Composition API код можно разбить на небольшие логические фрагменты, сгруппировать их и даже повторно использовать при необходимости. Давайте рассмотрим небольшой пример, чтобы понять разницу в подходе к структуре кода между Options API и Composition API.
Вот как выглядел бы наш код в Options API:
<template>
<div>
<div>count: {{ count }} {{ isGreaterthanFive }}</div>
<button @click="increase()">Increase Count</button>
<input type="text" name="user" v-model="name" id="" />
<div>{{ printUser }}</div>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
name: "",
};
},
methods: {
increase() {
this.count++;
},
},
computed: {
isGreaterthanFive() {
return this.count > 5 ? "Greater than 5" : "not Greater than 5";
},
printUser() {
return this.name ? `Name is ${this.name}` : "Use Not Stated";
},
},
};
</script>
Теперь, с помощью Composition API тот же самый код можно разбить на небольшие фрагменты на основе логики, которую они выполняют, и это будет выглядеть примерно так:
<script setup>
import { ref, computed } from "vue";
// Логика подсчета
const count = ref("");
const increase = () => {
count.value++;
};
const isGreaterthanFive = computed(() => {
return count.value > 5 ? "Greater than 5" : "not Greater than 5";
});
// Логика именований
const name = ref("");
const printUser = computed(() => {
return name.value ? `Name is ${name.value}` : "Use Not Stated";
});
</script>
<template>
<div>
<div>count: {{ count }} {{ isGreaterthanFive }}</div>
<button @click="increase">Increase Count</button>
<input type="text" name="user" v-model="name" id="" />
<div>{{ printUser }}</div>
</div>
</template>
Согласно официальной документации Vue, Composition API имеет много преимуществ по сравнению с API Options, среди которых:
Больше повторного использования логики.
Более гибкая организация кода.
Улучшенный интерфейс типов, поскольку Vue 3 написан на языке Typescript.
Меньший продакшн-бандл и меньшие накладные расходы.
Composition API — это, безусловно, огромный шаг вперед по сравнению с Options API, поскольку он дает нам возможность использовать возможности JavaScript в наших проектах Vue.js в полной мере. Правда, на освоение Composition API нужно будет потратить немного больше усилий, но оно того стоит. Ознакомьтесь с нашим курсом по Composition API Vue 3 — в нем вы найдете подробное руководство по использованию всего потенциала Composition API с примерами реальных юзкейсов.
Teleport
Teleport попросту поражает воображение тем, как он работает. Представьте себе, что можно перенести элемент из одной части DOM в другую. Teleport позволяет нам сохранять разметку внутри компонента и при этом визуально представлять его в другом месте DOM.
Идеальным примером использования телепорта являются модалки. Давайте вкратце рассмотрим один пример:
//AppModal.vue
<template>
<Teleport to="body">
<div>
<div class="modal_content">
</div>
<div class="modal_title">
<h2>This is my modal</h2>
</div>
<div class="modal_info">
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dolores itaque
inventore dignissimos suscipit delectus, ipsa repellat minima et vitae
perspiciatis quasi unde earum corporis labore at in temporibus repudiandae
totam
</p>
</div>
</div>
</div>
</Teleport>
</template>
//App.vue
<template>
<div>
<button @click="isOpen = true">Open Modal</button>
<AppModal v-if="isOpen" />
</div>
</template>
Посмотрим на результаты:
В нашем примере модальный компонент будет отображаться в теле как непосредственный дочерний компонент, даже если он расположен по-другому.
State Driven CSS
Работая с Vue.js вы, возможно, привыкли применять различные классы к тегам на основе какой-нибудь логики в вашем коде. Это связано с тем, что нам может потребоваться реактивно обновлять класс элемента в зависимости от определенных условий.
Например, если в переменную check
установлено значение true
, то нам нужно, чтобы div
отображался красным, в противном случае — синим. Для таких случаев часто пишут код следующего вида:
<div :class="check === true ? 'red' : 'blue'">
Hello World
</div>
В Vue 3 можно помещать реактивные переменные Vue непосредственно в CSS, что позволяет избежать создания дополнительных классов.
Давайте рассмотрим простой пример. Предположим, что в нашем шаблоне Vue имеется следующий скрипт:
<script setup>
import { ref } from 'vue'
const color = ref('#ff0000');
if(check == true) {
color.value = '#0000ff';
}
</script>
<template>
<input value="Hello World" />
</template>
Все предельно просто, не так ли? Если check
равна true
, то переменная color
принимает значение '#0000ff'. В противном случае она будет установлена в '#ff0000'. В Vue 3 мы можем напрямую ссылаться на color
прямо в CSS, используя v-bind
:
<style>
input {
color: v-bind(color)
}
</style>
Теперь color
обновляется реактивно, и цвет ввода будет меняться на тот, который задан в переменной color
. Это означает, что вы можете избежать неудобной логики в HTML-тегах и использовать JavaScript-переменные непосредственно в CSS, что, на мой взгляд, просто замечательно.
DefineEmits
defineEmits
— это макрос в Vue.js Composition API, позволяющий объявить события, которые компонент может передавать своему родителю. Он указывается внутри
в компоненте, и помогает сделать API компонента более наглядным и самодокументированным.
Давайте посмотрим на пример использования defineEmits
:
<!-- MyComponent.vue -->
<script setup>
import { defineEmits } from 'vue'
const emit = defineEmits(['my-event'])
function triggerEvent() {
emit('my-event', 'payload')
}
</script>
В данном примере мы объявляем, что компонент может генерировать событие под названием my-event
. Затем мы используем функцию emit
, возвращаемую defineEmits
, чтобы выдать это событие с полезной нагрузкой (payload) при вызове функции triggerEvent
.
Это очень удобно, поскольку позволяет документировать события компонентов в одном месте в случае, если в одном компоненте происходит несколько событий. Кроме того, теперь мы можем проверять полезную нагрузку.
<script>
export default {
// определяем как объект для проверки
emits:{
// или предоставляем функцию для проверки
// возвращает истинные значения для валидных, ложные - для невалидных
'check-name'(payload){
return !!(typeof payload === 'string')
}
},
data() {
return {
name:''
}
},
methods: {
sendData() {
this.$emit('check-name', this.name)
}
}
}
</script>
Suspense
<Supense> — это встроенный компонент Vue.js для организации асинхронных зависимостей в дереве компонентов. Он позволяет отображать состояние загрузки в ожидании разрешения нескольких вложенных асинхронных зависимостей в дереве компонентов.
Это позволяет отображать состояния загрузки или ошибок верхнего уровня в ожидании разрешения вложенных зависимостей, таких как компоненты с асинхронным хуком setup()
или асинхронные компоненты.
<Supense>
имеет два слота: #default
и #fallback
. Содержимое слота default
показывается, если это возможно, а содержимое слота fallback
показывается при ожидании разрешения асинхронных зависимостей.
Обратите внимание, что <Supense>
является экспериментальной фичей, и ее API может измениться до того, как она достигнет стабильного состояния. Но Nuxt 3 использует <Supense>
, и поэтому не стоит беспокоиться о том, что в ближайшее время она претерпит какие-либо изменения. Но тем не менее это потрясающая функция, так что давайте взглянем на нее в действии:
//PostComments.vue
<script setup>
import axios from 'axios'
const response = await axios.get('https://dummyjson.com/comments')
const comments = await response.data.comments
</script>
<template>
<div>
<div>Comments</div>
<ol>
<li v-for="comment in comments" :key="comment">{{ comment.body }}</li></ol>
</div>
</template>
//App.vue
<script setup>
import PostComments from './components/PostComments.vue';
</script>
<template>
<Suspense>
<template #default>
<div style="display: flex"><PostComments /></div>
</template>
<template #fallback>
<div>loading</div>
</template>
</Suspense>
</template>
С помощью приведенного выше кода наш компонент PostComments.vue
получает из нашего API список комментариев. В ожидании ответа от API мы можем отображать наш индикатор загрузки с помощью <Supense>
до тех пор, пока PostComments.vue не получит ответ.
Заключение
В заключение можно сказать, что переход от Vue 2 к Vue 3 стал для нас захватывающим событием, открывшим множество новых функций, которые по-новому раскрывают возможности веб-разработки.
Благодаря Composition API, Teleport, State driven CSS, Suspense и еще многим другим функциям, не упомянутым в этой статье, Vue 3 предоставляет нам множество инструментов для создания более быстрых, модульных и визуально динамичных приложений. Команда разработчиков Vue.js продолжает совершенствовать этот замечательный фреймворк, добавляя в него новые интересные фичи. Если вы все еще сидите на Vue.js 2, то самое время обновиться. Команда разработчиков Vue.js объявила, что поддержка Vue.js 2 прекратится к концу этого года (2023).
В заключение приглашаем всех желющих на открытый урок, на котором рассмотрим возможности библиотеки компонентов Quasar с Vue. Записаться можно на странице курса «Vue.js разработчик».
devprodest
Очень странно видеть подобную статью сейчас, учитывая что vue3 уже довольно давно вышел из беты ????
a-tk
Очень странно видеть такую статью от конкретно этого автора до выхода какой-нибудь Vue 5 или Vue 6