Pull to refresh
73.25
SimbirSoft
Лидер в разработке современных ИТ-решений на заказ

Хочу перемен: почему пора переходить на Vue 3

Reading time10 min
Views30K

Привет! Меня зовут Влад, я frontend-разработчик в компании SimbirSoft. Мне приходилось создавать приложения как на старых версиях Vue, так и на новых. Причем многие из моих коллег вполне успешно разрабатывают на Vue 2 и не спешат переходить на Vue3, даже спустя два года после релиза.

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

В этой статье попытался раскрыть новшества, которые могут стать «триггером» для миграции на новую технологию для обеих заинтересованных групп. Поговорим об экосистеме Vue 3, о новинках и пользе для разработчиков и бизнеса. И, разумеется, сравним Vue 2 и Vue 3 с технической точки зрения. Также рассмотрим одно из главных нововведений фреймворка – Composition API, раскроем технические нюансы и определим лучшие кейсы использования нового API.

История появления Vue

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

Создателем и главным разработчиком фреймворка является бывший работник Google Эван Ю. Первый коммит Vue был сделан в июне 2013 года и назывался Seed.js. Но, как выяснилось, имя seed было уже занято в npm, и название изменили на Vue.

Эван изначально писал фреймворк, который понравился бы ему как разработчику. Но первые несколько сотен звезд на GitHub мотивировали его создать продукт, который будет приятно и эффективно использовать.

Сейчас Vue – это крупнейший проект, который пользуется колоссальной финансовой и технической поддержкой партнёров и разработчиков из всего мира. В итоге то, что изначально задумывалось как инструмент для внутреннего пользования компании, переросло в один из лучших фреймворков для JavaScript.

Преимущества Vue 3

Концепция и основная идея новой версии Vue 3 возникли в 2018 году. На текущий момент времени с момента выхода Vue 3 версии прошло почти два года (дата релиза – сентябрь 2020 года).

Она включает в себя масштабные изменения в исходном коде и новый API. В ней также значительно улучшена производительность – в среднем 1,5-2 раза быстрее прошлой. Исходный код фреймворка был переписан с нуля, а при помощи использования TypeScript изменена система реактивности. А Vetur, официальное расширение VSCode, теперь поддерживает проверку типов у шаблона и свойств с использованием улучшенной внутренней типизации Vue 3.

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

Преимущества для разработчиков

Улучшенная интеграция с TypeScript

Vue 3 был полностью переписан на TypeScript и на текущий момент обеспечивает полноценную поддержку TypeScript. Все официальные пакеты Vue 3 поставляются со встроенными объявлениями типов, которые должны работать «из коробки».

А Composition API хорошо работает с типизацией данных в приложении.

Новые API для крупных приложений

Vue 3 предоставляет совершенно новый API Composition API - это мощнейшее решение, которое в полной мере разрешает проблемы Options API Vue 2 версии, а также предоставляет расширенные возможности в декларировании и управлении данными в фреймворке. Новый API позволяет облегчить реализацию сложных архитектурных решений в крупных и средних приложениях, по средствам обеспечения логической связанности и возможности повторного использования, похожую на хуки в React.

Порог входа

Vue придерживается консервативного подхода к созданию шаблонов и стилей, которые отделены от логики приложений и используют HTML и CSS. Для многих программистов это более привычно и облегчает постепенную миграцию существующих приложений.

Таким образом, исполнителю нужно меньше опыта, чтобы вносить доработки в текущую кодовую базу на Vue.

Фреймворк также отличает гибкость и модульность – можно моментально приступить к созданию приложения, не тратя лишнее время на конфигурирование c помощью инструмента командной строки VUE CLI.

Архитектура приложений

Vue использует подход ViewModel из шаблона MVVM. Он хорошо работает для более крупных приложений, используя двустороннюю привязку данных. Основная цель Vue – дать простой и гибкий уровень представления, а не полноценный фреймворк.

Документация

Разработчики Vue здесь очень постарались. Есть сайт с документацией, подробным описанием на нескольких языках и ответами сообщества на разные вопросы. А руководство и справку по методам API иногда даже признают лучшими в отрасли.

Остальные преимущества:

  • Новая концепция реактивности.

  • Улучшенная оптимизация и производительность.

  • Composition API.

  • Практически полная обратная совместимость с API второй версии.

  • Паттерн для повторного использования логики компонентов.

Преимущества для бизнеса

Безопасность

Хотя автоматически защитить приложения от XSS и других уязвимостей невозможно, разработчики Vue могут санитизировать HTML-код перед реализацией или использовать внешние библиотеки для защиты от атак. В тех случаях, когда вы знаете, что HTML безопасен, можно явно отображать содержимое HTML и защищать приложение до и после рендеринга. Исходя из последних статистических данных, следует отметить, что последняя уязвимость была обнаружена во второй версии Vue

Улучшение производительности

Vue 3 показывает значительные улучшения производительности. Если вы работаете с продуктом, который требует быстрого обновления содержимого и контента, выбор очевиден – это Vue 3. Новая версия имеет следующие показатели:

Поддержка

В будущем разработчики Vue, скорее всего, прекратят поддержку версии 2.x. Выбирая Vue 3, можно получить поддерживаемый и улучшаемый инструмент на годы вперёд.

Остальные преимущества Vue 3:

  • Улучшенная адаптация под большие и средние проекты.

  • Ориентация на современные вспомогательные инструменты, в частности, улучшена поддержка TypeScript.

  • Новые функциональные возможности для решения бизнес-задач.

  • Улучшение процессов разработки и отладки продукта на всех этапах.

Ключевые функциональные преимущества Vue 3

В этом разделе рассмотрим самые интересные функциональные улучшения новой версии Vue.

Изменённые алгоритмы сравнения виртуального DOM

Процесс изменения реального DOM дерева в Vue построен на вызове функции, которая сравнивает два объекта Vnode (oldNode, vNode), и последующем патчинге изменений в DOM браузера. В Vue 2 такой алгоритм был построен на сравнении всех узлов без фокуса на тип узла.

Концептуальная особенность алгоритма сравнения Vue 3 – сравниваются только Vnode элементы с динамической привязкой, а статические игнорируются.

Рассмотрим следующий пример:

<div> <p> Привет, {{username}} </p> <p> Приятно с тобой познакомиться </p>
<p> Время уже позднее, увидимся завтра </p></div>

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

Статический подъем

Для лучшего понимания концепции статического подъема рассмотрим однородную структуру шаблона компонента на следующем примере:

<div id="app">
	<div>
		<div>SimbirSoft — компания по разработке программного обеспечения.</div>
		<div>{{ contentDynamic }}</div>
	</div>
</div>

А теперь посмотрим на render-функцию для версий Vue 2 и Vue 3

Vue 2

function render() {
  var vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c('div', {
    attrs: {
      "id": "app"
    }
  }, [_c('div', [_c('div', [_vm._v(" " + _vm._s(_vm.msg) + " ")]), _c('div',
    [_vm._v(
      " SimbirSoft -- компания по разработке программного обеспечения. "
    )])])])
}

Во Vue 2 независимо от того, является ли элемент статическим, он повторно создается в render-функции. Затем рендерится в шаблоне, задействуя при этом больше ресурсов.

Vue 3

import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
 
const _hoisted_1 = { id: "app" }
const _hoisted_2 = /*#__PURE__*/_createElementVNode("div", null, "SimbirSoft — компания по разработке программного обеспечения.", -1 /* HOISTED */)
 
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("div", _hoisted_1, [
    _createElementVNode("div", null, [
      _hoisted_2,
      _createElementVNode("div", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */)
    ])
  ]))
}

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

Новая концепция реактивности

Реактивность – это механизм декларативного обновления данных в шаблоне, которые объявлены в коде. Во Vue 2 такой механизм строился на «геттерах» и «сеттерах» путём переопределения свойств объекта в инстансе Vue c помощью Object.defineProperty.

Во Vue 3 концепция реактивности полностью построена на Proxy. Это объект, который содержит в себе другой объект или функцию и позволяет «перехватывать» их.

Proxy во Vue 3 решает некоторые проблемы, присущие системе реактивности Vue 2. Например, добавление новых реактивных свойств в объект либо слежение за всем объектом, а не за единичным свойством. Подробнее про реактивность в новой версии можно прочитать здесь.

Конечно, в целом, концептуальных изменений гораздо больше. По ссылкам ниже можно найти еще несколько дополнительных интересных особенностей:

А мы перейдем к рассмотрению одного из главных нововведений Vue 3.

Composition API

Composition API – это совершенно новое решение организации компонентов в Vue 3. Оно представляет собой набор API:

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

Улучшенная организация кода в компонентах

Рассмотрим структуру двух совершенно одинаковых компонентов для взаимодействия с постами с точки зрения использования разных API.

Options API

<script>

import ***axios*** from 'axios';

export default {

data() {

	return {
			
		posts: [],
		
		authorPosts: [],
		
		favoritePost: null,
		
	}

},

mounted() {

	this.fetchPosts();

},

methods: {

	async fetchPosts() {
	
		this.posts = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data;
	
	},
	
	async getPostByAuthor(id) {
	
		this.authorPosts = (await axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${id}`)).data;
	
	},
	
	async getCommentsByPost() {
	
		this.comments = (await axios.get('https://jsonplaceholder.typicode.com/posts/1/comments')).data;
	
	},

	addPostToFavorite(id) {
	
		this.favoritePost = this.posts.find(post => post.id === id);
	
	},

},

computed: {

	getFavoritePostId() {
	
		return this.favoritePost?.id;
	
	},

}

}

</script>

Composition API

<script>
import {ref, computed} from 'vue';
import axios from 'axios';

export default {
 setup() {
   /* region posts */
   const posts = ref([]);
   (async () => {
     posts.value = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data;
   })();

   const authorPosts = ref([]);
   const getPostByAuthor = async (id) => {
     authorPosts.value = (await axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${id}`)).data;
   };
   /* endregion */

   /* region favoritePosts */
   const favoritePost = ref(null);
   const addPostToFavorite = (id) => {
     favoritePost.value = posts.value.find(post => post?.id === id);
   }

   const getFavoritePostId = computed(() => {
     return favoritePost.value?.id;
   })
   /* endregion */

   /* region comments */
   const comments = ref([]);
   const getCommentsByPost = async (postId) => {
     comments.value = (await axios.get(`https://jsonplaceholder.typicode.com/posts/${postId}/comments`)).data;
   };
   /* endregion */

   // other logic
   // other logic

   // region return
   return {
     posts,
     comments,
     addPostToFavorite,
     getPostByAuthor,
     getFavoritePostId,
     getCommentsByPost,
   }
   // endregion
 }
}
</script>

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

Декомпозиция и повторное использование кода

Методы, которые предоставляет нам Vue 2 для решения проблем декомпозиции и переиспользования кода в больших компонентах, иногда приводят к побочным эффектам. Например, Mixins может перезатереть уже существующий функционал, а Provide Inject, исходя из документации, рекомендовано использовать не во всех случаях. Кроме того, по умолчанию данные, монтируемые с помощью provide/inject, не реактивны.

С новым API мы можем инкапсулировать логику взаимодействия с постами и комментарии отдельно, а также переиспользовать в любом компоненте с помощью хука. Рассмотрим на примере.

Для наглядности упростим компонент до минимального функционала: получение и добавление поста в избранное. Логику вынесем за пределы компонента.

<script>

import { onMounted } from 'vue';
import usePosts from '@/logic/posts';

export default {
 setup() {
   /* region posts */
   const { fetchPosts, addPostToFavorite, favoritePost, posts } = usePosts();

   onMounted(async () => {
     await fetchPosts();
   })

   /* endregion */

   // region return
   return {
     addPostToFavorite,
     favoritePost,
     posts,
   }
   // endregion
 }
}
</script>

Наш внешний файл с логикой

import { ref } from 'vue';
import axios from 'axios';

const posts = ref([]);
const favoritePost = ref(null);

export default function usePosts () {

 const fetchPosts = async () => {
   posts.value = (await axios.get('https://jsonplaceholder.typicode.com/posts')).data;
 }

 const addPostToFavorite = (id) => {
   favoritePost.value = posts.value.find(post => post?.id === id);
 }

 return {
   posts,
   favoritePost,
   addPostToFavorite,
   fetchPosts,
 }
}

Как мы видим, с помощью новых возможностей легко отделить логику в внешний файл и использовать, где потребуется. Поле для масштабируемости данного подхода огромно. Вплоть до отказа от всеми известного менеджера состояний Vuex. С помощью данного подхода мы можем организовывать свой store без использования сторонних библиотек. Тем, кто любит архитектурные решения, рекомендуем взглянуть на npm-пакет Pinia.

А благодаря синтаксическому сахару в виде дополнительного атрибута "setup" в тэге <script> (доступно с версии 3.2),  данные в компоненте можно определять еще проще.

<script setup>

import { onMounted } from 'vue';
import usePosts from '@/logic/posts';
const { fetchPosts, addPostToFavorite, favoritePost, posts } = usePosts();

onMounted(async () => {
 await fetchPosts();
})

</script>

Магия! Не правда ли?

Улучшенная поддержка TypeScript

В старой версии для внедрения поддержки TypeScript необходимо было использовать классовые компоненты и декораторы. Это не всегда удобно и в целом усложняет процесс разработки.

С появлением Composition API всё изменилось. Новый синтаксис позволяет использовать типизацию с минимальными трудозатратами. Рассмотрим на примерах.

ref

import { ref } from 'vue'
import type { Ref } from 'vue'

const year: Ref<string | number> = ref('2020')

year.value = 2020 // отлично

reactive

import { reactive } from 'vue'

interface Post {
 id: number;
 title: string;
}

const post: Post = reactive({ id: 1222, title: 'Название' })

computed

import { computed } from 'vue'

const postId = computed<number>(() => {
 return post.id;
})

Конечно, на примере более сложных сущностей всё может быть не так просто, но это только с первого взгляда. Если вы знакомы с типизацией Vue 2, то поймете, насколько всё стало лучше и удобнее.

Резюме

Для меня как разработчика, преимущественно на фреймворке Vue, новая версия показала себя с хорошей стороны. По сути, это тот же продукт, который не потерял концепцию декларативного инструмента и в то же время решил проблемы прошлых версий. Стало легче работать с большими объемами данных. К тому же, в третьей версии улучшена поддержка типизации TypeScript. Кроме этого, мы получили новые функциональные возможности, которые предоставляют улучшение процесса разработки в целом.

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

Если на момент релиза это все еще был новый инструмент со своими подводными камнями, практически отсутствием npm пакетов и фреймворков, адаптированных под новую версию, то сейчас можно с уверенностью сказать, что Vue 3 – оптимальная версия фреймворка на текущий момент.

Надеемся, статья была вам полезна!

Больше кейсов и полезных материалов для владельцев продуктов - в нашем ВК и Telegram.

Tags:
Hubs:
Total votes 8: ↑8 and ↓0+8
Comments25

Articles

Information

Website
www.simbirsoft.com
Registered
Founded
Employees
1,001–5,000 employees
Location
Россия