Главная » Css live » Как создавать Vue-компоненты, словно профи

Как создавать Vue-компоненты, словно профи

Перевод статьи How To Build Vue Components Like A Pro 😎 с сайта blog.bitsrc.io для css-live.ru, автор — Rajat S

Vue — один из самых быстро растущих фреймворков в современном мире. Представленный как «интуитивный, быстрый и компонентный» инструмент на базе паттерна MVVM для построения интерактивных интерфейсов, Vue стал любимым JavaScript-фреймворком для разработки интерактивных веб-приложений и интерфейсов для каждого разработчика. Его 97 тыс. звёзд на GitHub с релиза в 2014 яркое тому подтверждение.

В отличие от Angular, который основан на старой доброй архитектуре Model-View-Controller (модель, представление, контроллер), Vue следует системе Model-View-View-Model (модель, представление, модель представления)

Vue выделяется ещё одной прекрасной штукой — своими однофайловыми компонентами. Что означает, что для шаблона, скриптов и стилей нужен всего один файл .vue.

<template> <p>({greeting })</p>
</template> <script> module.exports = { data: function () { return { greeting: 'Hello' } } }
</script> <style scoped> p { font-size: 2em; text-align: center; }
</style>

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

Начало работы над приложением

Приложения во Vue можно создать многими различными способами. Если вы новичок, можете поиграться с этим примером «Hello World» на JS Fiddle.

В этой статье для создания проекта на Vue я использую Vue CLI (интерфейс командной строки). Для начала, чтобы установить Vue CLI, откройте в вашей системе консоль:

$ npm install --global @vue/cli

Теперь можете создать проект на Vue! Так что, теперь сделаем вот что:

$ vue create vue-app
$ cd vue-app

Это создаст новый проект на Vue под названием vue-app. Название может быть каким угодно.

Создадим компоненты Vue с помощью vue-class-component

В коде выше можно видеть функцию data, возвращающую объект. При желании передать какие-либо обработчики вам пришлось бы писать объект method.

Vue-class-component сокращает процесс разработки, позволяя разработчикам добавлять свойства данных и обработчики прямо как свойства для класса.

Откройте ваш проект прямо в редакторе кода (Я ❤️ VS Code). В папке src есть два файла: App.vue и main.js.

Уже работавшие с библиотеками вроде React разработчики могут заметить, что этот main.js — эквивалент реактовского index.js. Что означает, что это и есть файл, запускаемый командами вроде yarn serve или yarn build.

Замените код в файле main.js на этот:

import 'tailwindcss/dist/tailwind.css';
import Vue from 'vue';
import App from './App'; new Vue ({ el: '#app', render: h => <App />,
});

В основном, мы сначала выбираем элемент div с id=”app” из файла public/index.html, а после отображаем компонент App внутри него.

Теперь нужно создать этот компонент App в файле App.vue. Откройте файл App.vue и замените код по умолчанию на этот:

<template> <h1 @click="onClick"> {{message}} </h1>
</template> <script>
import Vue from 'vue';
import Component from 'vue-class-component';
export default Component({})( class App extends Vue { message = 'Batman'; onClick() { this.message = 'Bruce Wayne'; } }
);
</script>

Здесь я первым делом создал простой шаблон с элементом div, в котором есть сообщение. Код в теге <script> импортирует пакет Vue и функцию Component из vue-class-component. Вам также нужно установить этот пакет в ваш проект.

$ yarn add vue-class-component

Далее я декорировал класс App с помощью функции Component. У этой функции есть объект, в который можно передать опции.

Если вы используете VS Code, то увидите, что теперь у вас на App выскакивает ошибка. Это потому, что VS Code по умолчанию не допускает экспериментальных декораторов. Для решения этой проблемы создайте новый файл jsconfig.json в корневой директории проекта. Здесь вы указываете компилятору Vue разрешать экспериментальные декораторы в коде:

{ "compilerOptions": { "experimentalDecorators": true }
}

Перезагрузите редактор и ошибка исчезнет!

Теперь ответим на вопрос «Почему я мне стоит использовать vue-class-component вместо традиционных компонентов Vue

В традиционном компоненте вам требуется написать функцию data, возвращающую объект. Чтобы изменить что-то в вашем компоненте, вам надо будет написать еще такие методы, как onClick.

const TraditionalComp = { data() { return {message: "Batman"} }, methods:{ onClick() { this.message = "Bruce Wayne" } }
}

Но в vue-class-component вы пишите метод onClick напрямую. Всё что остаётся сделать — это сослаться на него в template. Это можно сделать, написав @click="onClick" в теге h1 в шаблоне.

Запустите приложение Vue с помощью команды yarn serve и вы увидите, что оно работает вот так:

Определяем свои пропсы (props) с помощью vue-property-decorator

Для определения свойств прямо в классе можно также использовать vue-property-decorator. И это тоже делается с помощью простого декоратора @Prop(). Этот метод объявления пропсов позволяет сохранять классы простыми.

Первым делом установите в проект пакет vue-property-decorator:

$ yarn add vue-property-decorator

Ещё одна замечательная вещь этого пакета — в нём уже содержится vue-class-component. Поэтому вместо способа выше можете импортировать Component из пакета vue-property-decorator.

Замените код в файле App.vue на код ниже:

<template> <h1 @click="onClick"> {{message}} </h1>
</template> <script>
import Vue from 'vue';
import {Component, Prop} from 'vue-property-decorator';
export default Component({})( class App extends Vue { @Prop({default: 'Batman'}) message; onClick() { this.message = 'Bruce Wayne'; } }
);
</script>

Здесь я первым делом импортирую Component и Prop из пакета vue-property-decorator. Затем внутри класса App я использую декоратор @Prop для установки значения сообщения по умолчанию.

И это всё! Теперь вы передаёте в ваш код сообщение в качестве пропса, и у него есть значение по умолчанию.

Определяем место контента в компонентах с помощью Vue-слотов

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

Вернёмся в файл main.js и перепишем код в render:

render: h => ( <App> <h1>Superman</h1> </App>
)

Сейчас вы не увидите изменений в браузере. Это потому, что вы совсем не указали места для нового текста в template в файле App.vue. Вот где слоты вступают в игру.

В template App.vue напишите два новых слота, расположенных до и после оригинального тега h1

<template> <div> <slot name="header"></slot> <h1 @click="onClick"> {{message}} </h1> <slot name="footer"></slot> </div>
</template>

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

Теперь в файле main.js добавьте атрибут slot="footer" к новому тексту. После этого ваш текст отобразится.

Но теперь метод render немного громоздкий. Давайте посмотрим, как это можно исправить с помощью слотов.

Используем слоты для создания раскладки

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

Создайте новый файл Layout.vue в папке src/components. Внутри этого файла напишите элемент template как показано ниже:

<template> <div> <slot name="header"></slot> <slot name="body"></slot> <slot name="footer"></slot> </div>
</template>

Теперь в файле App.vue удалите всё внутри тега template. Затем в теге script импортируйте только что созданный Layout.vue.

import Layout from './components/Layout';

Вам также нужно сказать декоратору Component, что вы используете компонент Layout.

export default Component({ components: {Layout},
})

Теперь можете использовать Layout в качестве компонента в теге template. Ещё я добавлю немного элементов с текстом.

<template> <Layout> <h1 slot="header">How To Build Vue Apps Like A Pro 😎</h1> <h2 slot="body"> by Rajat S</h2> <h3 slot="footer">Technical Content Writer</h3> </Layout>
</template>

Убедитесь, что вы добавили атрибут slot с подходящим именем, иначе элементы с текстом не отобразятся.

Передача пропсов с помощью областей видимости слотов Vue (Vue slot scope)

При комбинировании компонентов со слотами можно передавать данные компонентов в слоты с помощью slot-scope. Можно передавать пропсы вглубь из родительских компонентов в дочерние, не связывая их друг с другом.

В файле App.vue в теге template оберните Layout в тег Settings.

<template> <Settings> <Layout slot-scope="{header}"> <h1 slot="header">{{header}}</h1> <h2 slot="body"> by Rajat S</h2> <h3 slot="footer">Technical Content Writer</h3> </Layout> </Settings>
</template>

Импортируйте Settings в теге script

import Settings from './components/Settings.vue';

Сообщите декоратору Component, что у вас будет Settings в качестве компонента.

export default Component({ components: {Layout, Settings},
})

Теперь реально создайте компонент Settings. Для этого в src/components создайте файл Settings.vue, и напишите внутри него этот код:

<template> <div> <slot :header="header"></slot> </div>
</template>
<script>
import Vue from 'vue';
import Component from 'vue-class-component';
export default Component({})( class Settings extends Vue { header = 'How To Build Vue Apps Like A Pro 😎'; }
);
</script>

В теге template у меня есть корневой div со слотом внутри. В этом слоте я связал :header с header.

Далее в теге script я вначале импортирую пакет Vue и декоратор Component из пакета vue-class-component.

Затем в декораторе Component я создал класс Header. В этом классе содержатся данные, которые я хочу передать в пропс header.

Передача пропсов в функциональные шаблоны

Функциональные шаблоны позволяют создать компонент, в котором есть только тег template, а props доступны из шаблона.

В папке src/components создайте новый файл Header.vue и напишите этот код внутри него:

<template functional> <h1 slot="header">{{props.header}}</h1>
</template>

Термин functional здесь нужен, чтобы указать, что в этом файле есть только простой template. Повторите это в файлах Body.vue и Footer.vue.

Вернитесь в файл App.vue и перепишите template так:

<template> <Settings> <Layout slot-scope="{header, body, footer}"> <Header slot="header" :header="header"></Header> <Body slot="body" :body="body"></Body> <Footer slot="footer" :footer="footer"></Footer> </Layout> </Settings>
</template>

Вам также нужно написать строку import для Header, Body и Footer в теге script в этом файле:

import {Header, Body, Footer} from './components';

И сообщите декоратору Component, что вы используете их как компоненты.

export default Component({ components: { Settings, Layout, Header, Body, Footer, },
})

Но этот код по-прежнему не будет работать, поскольку строка import, которую вы только что написали, не совсем корректна. Для решения этой проблемы создайте новый файл index.js в src/components.

export {default as Header} from ‘./Header.vue’;
export {default as Body} from ‘./Body.vue’;
export {default as Footer} from ‘./Footer.vue’;

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


Используем Bit для компонентов Vue

Bit — платформа для использования компонентов во множестве приложений или проектов сразу, при этом синхронизируя их. При работе с компонентами Vue.js Bit — отличный способ работать сообща, разрабатывать компоненты из разных проектов, структурировать их, синхронизировать изменения и управлять всем этим. Попробуйте сами.

Заключение

Vue — программная технология, которая широко используется для веб-разработки по всему миру. Vue — по сути JavaScript-фреймворк со множеством разных инструментов на выбор для построения пользовательских интерфейсов.

Одна из главных причин успеха Vue — что его легко выучить, а делать на нём потрясающие приложения еще легче.

Я надеюсь, что благодаря этой статье вы смогли познакомиться с Vue поближе и понять, как с его помощью можно создавать ещё лучшие приложения. Следите за подобными статьями по Vue, React и другими популярными фреймворками/библиотеками.

P.S. Это тоже может быть интересно: