Vue 3.0 — первый взгляд

от автора

Наконец-то руки дошли попробовать новую версию Vue. Я не собираюсь быть объективным в этой статье, я просто расскажу свои впечатления в процессе работы с новой версией, а также расскажу как её установить и начать работу уже сейчас.

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

Особенно много вопросов вызывает новый синтаксис, так называемый Composition API, который, к счастью, не заменит полностью привычный и всеми любимый Options API. В пользу новой композиции нам всюду предлагают подобную картинку:

Сравнение фрагментации кода в старом и новом синтаксисе
Сравнение фрагментации кода в старом и новом синтаксисе

Смахивает на вкусовщину. Мне удобнее написать метод и забыть, что у него внутри, главное — чтобы его имя правильно подсказывало что он делает. Наверное, для стороннего человека будет проще понять скомпонованную логику, и любителям TS зайдет. Что мы точно знаем — это то, что оба подхода останутся навсегда. Так что знать новую компоновку надо. А некогда единое сообщество разделится надвое.

На вопросы «зачем это или другое нововведение» дают один ответ: потому что это есть в React. Такая аргументация не очень вдохновляет, если я хочу, чтобы было как в реакте, я буду писать на реакте.

Давайте перейдем к созданию проекта.

Для тех кто не разобрался с установкой Vue 3, добро пожаловать под спойлер:

Установка Vue 3

Первый вариант подключения это через npm — набираем в консоли:

npm install vue@next

Эта команда просто скачивает пакет в папку node_modules. Синтаксис подключения в новой версии изменился, мы не будем его разбирать. Гораздо проще создать проект с помощью Vue CLI.

Второй вариант: для начала вам нужно обновить CLI. Снова открываем консоль :

npm install -g @vue/cli

Почему-то у меня не сработало обновление, тогда я обновил через yarn (да я иногда изменяю Vue с React):

yarn global add @vue/cli

Не знаю в чем была проблема, в случае чего, обновите через оба менеджера. Чтобы проверить версию, наберите в консоли:

vue -V

должно показать @vue/cli 4.5.6.

Создаем проект в нужной нам директории:

vue create hello-vue

Дальше нам предлагают три варианта на выбор. Выбираем вторую строку:

Default (Vue 3 Preview) ([Vue 3] babel, eslint)

После того как проект создался, переходим в директорию проекта:

cd hello-vue

Открываем проект в вашем любимом редакторе кода. Для VScode достаточно набрать в консоли:

code  .

Vue CLi заботливо создал для нас проект. Первое отличие сразу же бросается в глаза. Это файл main.js:

import { createApp } from 'vue' import App from './App.vue'  createApp(App).mount('#app')

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

Удаляем компонент HelloWorld.vue и все содержимое в файле App.vue.

В папке components создаем новый файл Card.vue со следующим содержимым:

<template>   <div>     <img :src="imgUrl" alt="cat pic" />     <h1>{{ catName }}</h1>     <p>       <i>{{ text }}</i>     </p>     <p>       <b>{{ website }}</b>     </p>   </div> </template>  <script> export default {   name: "Card",   props: {     id: String,     name: String,     text: String,     website: String,   },   computed: {     imgUrl() {       return `https://robohash.org/${this.id}?set=set4&size=180x180`;     },     catName() {       return this.name.replace(/[_.-]/gi, " ");     },   }, }; </script>

Компонент карточки получает несколько входящих данных props. Некоторые мы хотим изменить перед тем, как использовать их в шаблоне. Например, в имени заменяем все точки, нижние подчеркивания и дефисы на пробелы. Для этого мы привычно используем computed. Как этот же компонент будет выглядеть с новым синтаксисом? Для начала импортируем computed

<script> import { computed } from "vue"; ...

переписываем логику из computedв новую опцию setup вот так:

 setup(props) {     const imgUrl = computed(       () => `https://robohash.org/${props.id}?set=set4&size=180x180`     );     const catName = computed(() => props.name.replace(/[_.-]/g, " "));     return {       imgUrl,       catName,     };   },

Setup принимает переменную props, которая содержит все входные параметры.

Картинки для карточек, нарисованных милых котиков, мы берем с сайта robohash.org. Просто чтобы разбавить наше скучное занятие. А еще добавим ультрамодного неоморфизма в стили:

<style scoped> div {   width: 400px;   height: 380px;   position: relative;   background: #ecf0f3;   margin-bottom: 30px;   padding: 30px 5px;   border-radius: 32px;   text-align: center;   cursor: pointer;   font-family: "Montserrat", sans-serif;   font-size: 22px;   font-weight: semibold;   box-shadow: -6px -6px 10px rgba(255, 255, 255, 0.8),     6px 6px 10px rgba(0, 0, 0, 0.2);   color: #6f6cde; } </style>

Теперь вернемся к файлу App.vue. Он должен принимать данные для карточек с котиками и создавать карточки. Напишем его сразу на новом синтаксисе:

<template>   <div class="container">     <Card       v-for="cat in cats"       :id="cat.id"       :name="cat.username"       :text="cat.company.catchPhrase"       :key="cat.id"       :website="cat.website"     />   </div> </template>  <script> import { ref, onMounted } from "vue"; import Card from "./components/Card";  export default {   name: "App",   components: { Card },   setup() {     const cats = ref([]);     const fetchCats = async () => {       cats.value = await fetch(         "https://jsonplaceholder.typicode.com/users"       ).then((response) => response.json());     };     onMounted(fetchCats);     return {       cats,     };   }, }; </script>  <style> body {   background: #ecf0f3; } .container {   height: 100%;   display: flex;   flex-direction: row;   justify-content: space-around;   align-content: space-around;   flex-wrap: wrap;   padding: 30px 0px; } </style>

Если вы все сделали правильно, вот что вы должны увидеть в итоге:

Новыми для нас являются две фичи ref и onMounted

ref нужен нам, чтобы создавать реактивную переменную в методе setup(). Вот только пользоваться им немного по-другому. ref оборачивает наш массив в объект. Это нужно для двусторонней реактивности, ведь простые примитивы джаваскрипт передает как значение, а не как ссылки, в отличие от объектов. Теперь искомый массив доступен через переменную value этого объекта, и чтобы присвоить ему новое значение, придется писать вот так:

cats.value = data

А в шаблоне по прежнему используем просто cats

onMounted заменяет знакомый mounted. Как и все хуки жизненного цикла он будет доступен в setup под тем же именем, только с приставкой on. Для каждого метода придется вызывать onMounted заново. Напомню, что все эти манипуляции делались с одной целью, чтобы логику получения данных можно было написать вместе.


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

Полный код проекта доступен здесь.

Ну и небольшой вывод от меня. Создавать новые проекты и переводить старые(где это возможно) на новую версию фреймворка стоит. Несмотря на некоторые неоднозначные моменты, в ней есть и очевидные плюсы. Пользоваться новым синтаксисом или нет решать вам.

ссылка на оригинал статьи https://habr.com/ru/post/521250/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *