Vue — это front-end JavaScript фреймворк для создания пользовательских интерфейсов (UI) и одностраничных приложений (SPA). Vue 3 был выпущен уже давно, но до сих пор я не находил времени для его изучения, поскольку меня немного пугает необходимость изучать что-то новое.
Но больше нет оправданий. Я погружаюсь в Vue 3 и собираюсь написать свои впечатления о его сравнении с Vue 2. Если у вас, как и у меня, есть вопросы, такие как:
- Как настроить файлы компонентов в Vue 3?
- Что это за новый метод
setup()
? - Что такое API Composition (Vue 3) по сравнению с API Options (Vue 2)?
- Являются ли реквизиты, события и крючки жизненного цикла в основном теми же самыми? Или я столкнусь с большими изменениями?
- Как вообще начать работу с Vue 3?
Тогда эта серия статей будет полезна для вас! Читайте дальше, если вы заинтересованы в том, чтобы начать работу с Vue 3.
CLI — что мы получаем из коробки
Давайте начнем со сравнения настройки проектов Vue 2 и Vue 3 с помощью Vue CLI.
Vue CLI поможет вам загрузить новый проект Vue, предоставив вам все необходимые файлы для начала работы.
В Vue 2 достаточно было выполнить следующую команду в терминале (при условии, что сначала был установлен Vue), и CLI направлял вас в процессе настройки.
vue create YOUR-PROJECT-NAME
Хорошие новости! С Vue 3 все почти полностью аналогично. После установки Vue 3 вы можете просто ввести эту команду, и перед вами появится список для выбора. Вы можете выбрать либо Vue 2, либо Vue 3 для своего нового проекта.
Мне это нравится, поскольку это означает, что мне не придется полностью переходить на Vue 3, если окажется, что он мне не по душе. Я могу легко загружать проект на Vue 2 или Vue 3 после обновления до Vue 3.
На этот раз я выберу Vue 3, чтобы посмотреть, как этот проект сравнится с тем, что я получу из коробки с Vue 2. Я начну с рассмотрения файлов, которые, как я ожидаю, мне понадобятся.
Файлы проекта
Как пользователь Vue, я знаю, что три важных файла, которые заставляют Vue работать и отображаться на странице, следующие:
- index.html
- main.js
- App.vue.
Сначала я рассмотрю эти файлы, чтобы увидеть, есть ли заметные изменения между Vue 2 и Vue 3. Обратите внимание на скриншоте, что файловая структура проекта, созданного с помощью CLI, идентична как для Vue 2, так и для Vue 3. Однако если мы копнем внутрь и рассмотрим три файла, которые я назвал в списке выше, то обнаружим некоторые изменения.
index.html
При создании даже самой простой веб-страницы (не только в проектах Vue) файл index.html — это файл, который служит стартовой страницей по умолчанию, задавая основной скелет того, что мы видим на странице (базовая структура HTML).
Вот файл index.html, созданный в проекте Vue 2. И что интересно, точно такой же файл есть в проекте Vue 3.
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
Этот файл чрезвычайно важен, поэтому я первым делом проверяю его и смотрю, не изменилось ли что-нибудь между Vue 2 и Vue 3.
Файл index.html содержит элемент div
с id="app"
, и именно здесь Vue знает, что искать, чтобы вмонтировать приложение в DOM.
<div id="app"></div>
Vue использует этот div
в качестве точки входа для внедрения всех файлов Vue. Внутри этих файлов Vue происходит волшебство Vue, но именно первая точка входа div
вводит код Vue в основную HTML-страницу.
Поскольку этот файл идентичен в обоих проектах Vue 2 и Vue 3, это говорит мне о том, что, по крайней мере в этом аспекте, и Vue 2, и Vue 3 используют один и тот же подход к размещению файлов Vue в DOM — они ищут div
в файле index.html, и когда div
найден, приложение Vue присоединяется к этому конкретному элементу.
main.js
Файл main.js в проекте Vue — это место, где инициализируется сам экземпляр Vue. (Приложение Vue представляет собой объект Javascript под капотом — каждый уникальный проект Vue является объектом экземпляра объекта Vue. Он наследует свойства и методы, которые заставляют Vue работать так, как он работает).
В Vue 2 инициализация приложения выглядит следующим образом:
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: (h) => h(App),
}).$mount('#app')
Но в Vue 3 это выглядит следующим образом:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Очевидно, что это большое изменение. Я хочу понять оба варианта, поэтому сначала объясню, что происходит в Vue 2, а затем сравню с Vue 3.
Vue 2
Сначала я посмотрю, что происходит в Vue 2. Я заметил эти два важных утверждения:
import Vue from 'vue'
import App from './App.vue'
Функция конструктора Vue должна быть импортирована из Vue, чтобы ее можно было использовать для создания нового экземпляра Vue. App также импортируется (это файл App.vue в проекте), потому что мне нужен корневой компонент Vue, в котором будет находиться весь мой код Vue. Любые дочерние компоненты, которые я позже создам, будут входить в проект через этот файл App.
Далее, в файле Vue 2 main.js я вижу следующее:
new Vue({
render: (h) => h(App),
}).$mount('#app')
Здесь используется функция конструктора Vue. new Vue()
создает новый экземпляр объекта Vue. А в функцию конструктора Vue({...})
передается объект, который известен как объект options. Вот почему Vue 2 иногда называют API опций (хотя API опций — это всего лишь часть Vue 2). Опции — это такие свойства, как data, methods, mounted, computed и так далее.
В следующей строке я вижу render: h => h(App)
. Свойство render указывает Vue на то, что компонент должен быть отображен в формате HTML (render
— это функция, которая является частью API опций Vue). Вы можете прочитать в этой статье о том, почему используется h
, если вам интересно. Код в файле компонента App.vue передается в эту функцию рендеринга, поэтому он собирается в виде HTML (и еще кое-что, что заставляет Vue делать свою магию реактивности).
Метод $mount — это встроенный метод Vue, который вручную запускает монтирование экземпляра Vue.
Vue 3
В Vue 3 я вижу, что файл main.js выглядит совсем иначе:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Кажется, что здесь гораздо меньше кода. Вместо импорта функции-конструктора для создания экземпляра объекта Vue я вижу импортируемую функцию createApp
. Меня поражает, что инициализация происходит всего одной строкой кода, createApp(App).mount('#app')
.
Хотя здесь это не видно, функция createApp
на самом деле все еще использует конструктор new Vue()
внутри функции. Разница в том, что теперь создается копия экземпляра Vue. Вместо того чтобы использовать new Vue()
напрямую (и напрямую добавлять параметры конфигурации, которые будут влиять на все использования данного экземпляра Vue, что приведет к изменениям глобального состояния), функция createApp
создает копию, которую можно настроить отдельно. Заключив это в функцию, я получаю возможность создавать отдельные экземпляры Vue, и конфигурация каждого экземпляра не будет влиять на другие экземпляры.
Это улучшение, потому что теперь при необходимости легче создать два объекта Vue с отдельными конфигурациями. Вот пример настройки, которая позволяет это сделать:
import GlobalApp from './App.vue'
//Create one Vue app using same global app file and add unique configuration
const app1 = Vue.createApp(GlobalApp)
app.component('SearchInput', SearchInputComponent)
app.directive('focus', FocusDirective)
app.use(LocalPlugin)
//Create second Vue app using same global app file and add unique configuration
const app2 = Vue.createApp(GlobalApp)
app.component('Modal', ModalComponent)
app.directive('toolip', TooltipDirective)
app.use(DifferentPlugin)
Почему это полезно? Я могу только представить возможные ситуации. Возможно, если разные команды, использующие Vue, хотят создать один и тот же основной файл App, но добавить свои опции, плагины, возможности и т.д. Или, может быть, чтобы я мог создать что-то в качестве ядра, но затем разветвиться по разным путям, чтобы посмотреть, как работают различные конфигурации.
Какой бы ни была причина, наличие такой возможности сделало Vue лучше.
App.vue
Последний файл, на который я хочу взглянуть, чтобы увидеть, есть ли какие-либо различия из коробки, — это файл App.vue.
Файл App.vue — это корневой компонент, тот, который является отправной точкой для рендеринга кода Vue, когда приложение подключается к элементу DOM в файле index.html.
Сравнив App.vue в Vue 2 и App.vue в Vue 3, я вижу только одно отличие, и оно заключается в блоке шаблона.
Вот шаблон App.vue из Vue 2:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
А вот шаблон Vue 3 App.vue:
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</template>
Я удивлен тем, что в шаблоне больше нет необходимости в окружающем корневом div. Нам больше не требуется иметь один корневой элемент, как, например, здесь:
<template>
<div id="app">...</div>
</template>
В Vue 2 мы должны были предоставить один корневой элемент в качестве прямого дочернего элемента шаблона, но теперь в Vue 3 мы можем иметь много прямых дочерних элементов, т.е. несколько корневых элементов. Это устраняет все лишние div, которые появлялись вокруг HTML-кода каждого компонента.
Однако это означает, что если вы поместите в компонент атрибут, не являющийся корнем, и будете использовать многокорневые элементы, а не один корневой элемент, как в Vue 2, этот атрибут не будет отображаться в вашем компоненте, если вы явно не привяжете элемент к этим атрибутам. Просто кое-что, о чем следует знать.
Заключение
Пока что меня не слишком пугают изменения, которые я вижу в Vue 3 по сравнению с Vue 2, но я еще не перешел к главному.
В следующем посте этой серии я рассмотрю функцию setup()
, которая, вероятно, является самым важным изменением для понимания. Это будет хорошая возможность сравнить API Composition (который поставляется с Vue 3) с API Options (который был в Vue 2).
Пожалуйста, следуйте за мной в Twitter, если вы хотите погрузиться в Vue 3 вместе со мной!