CSS-live.ru

Как создавать 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. Это тоже может быть интересно:

14 комментариев

  1. Здравствуйте. Очень интересный пост. Правда мало что понял, но ваши слова последние о лёгкости обучения Vew очень заинтересовали. Что посоветуете?

    Я знаю javascript на начальном уровне: проходил курс javascript и Jquery на http://www.wisdomweb.ru.

    Сейчас хочу освоиться с node.js, научиться делать сайты (В настоящее время делаю их на php), но Express оттолкнул непонятными конструкциями.

  2. Прошу прощения, что правку оставляю здесь, не нашёл, куда лучше написать.

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

    Лишняя «я» после «Почему»

  3. Ну не знаю насчет профи, но этот подход используют те кто перешел или переходит с angular и ничего общего с профи этот подход не имеет. Это просто синтаксис аля angular like. Во vue сообществе такой подход не приветствуется.

    https://t.me/vuejs_ru телеграм чат vue

    1. В целом, vue-class-component предназначен для написания типизированных компонентов на Vue, и это не просто родной ангуляру TypeScript, это действительно более профессиональный подход для громоздких приложений. И почему такой подход не приветствуется сообществом? Репозиторий принадлежит vuejs, а сообщество, вроде, контрибьютит.

  4. Это, конечно, вкусовщина, но лично мне вот такой код не нравится)

    export default Component({})(
      class App extends Vue {
    // ...
    }
    });

    Мне больше традиционный export default {} импонирует) Который во *.vue файлах используется

  5. Ух как код побился.. В редактор прям жизненно необходима кнопка для вставки кода)

    p.s. уберите, пожалуйста, recaptcha’у. ух какая же это бесячая херня! Написание комментария занимает 2 минуты, а разгадывание этих тупых картинок — больше пяти..

  6. простите, но у автора шизофрения?

    зачем создавать проект с помощью npm? ПРАВИЛЬНО — чтобы потом вместо него использовать yarn!

    или давайте добавим импорт какого-то непонятного «tailwindcss», но как бы случайно пропустим что это и зачем нужно?

  7. Привет всем! На днях узнал о сервисе BAILRY. Сервис BAILRY — это бесплатная регулярная (периодическая) проверка доступности сайта. Возможно, кому-нибудь он пригодится! Есть там и платная услуга — для постоянного контроля доступности сайта. Удачи всем!

  8. У меня вопрос. Я новичок, закончил общее знакомство с JS, сейчас разбираюсь с Vue, прошу помочь, без насмешек и пафоса. Я установил Vue.js 2, произвел некоторые действия, ознакомился с localhost 8080, выключил всё. На следующий день после включения и начала работы, что мне надо сделать чтобы опять увидеть localhost8080, надо ли команды писать в Терминал и какие?

  9. Автор серьёзный говнокодер. Проявления этого множественны. Не воспринимайте эту статью серьёзно плз.

Оставить комментарий

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

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.