Эта статья является началом серии под названием «Создание повторно используемых компонентов с помощью Vue.js». Каждая статья проведет вас через создание определенного компонента пользовательского интерфейса и научит вас многим основам Vue на этом пути. Каждая статья будет основываться на последней, усложняясь по мере продвижения. Также будут представлены структура приложения и другие мнения.

Обновление - 13 апреля 2017 г.

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

Эй, помедленнее

Разве здесь нет нативного элемента кнопки, зачем вам для этого нужен специальный компонент?

  1. Общая функциональность
  2. Общие стили

Оба они помогут поддерживать наше приложение. Если функция должна быть добавлена, обновлена ​​или удалена, ее нужно исправить только в одном месте. Ча-цзин!

Предисловие

Эта статья предназначена для людей, которые уже имеют базовое представление о Vue и NPM. Основное внимание в этой статье уделяется JavaScript и его взаимодействию с DOM. Это означает, что CSS нельзя объяснить. Я не могу гарантировать, что что-либо из этой статьи будет работать в будущих выпусках. Я не могу гарантировать, что мои личные практики являются лучшими. Я не несу ответственности за длинные касательные, которые, казалось бы, не имеют смысла. Фух, теперь перейдем к хорошему.

Boilerplate

Я создал шаблонный базовый проект для использования. Настройка проекта не является предметом этой статьи. В этой статье предполагается, что вы имеете очень общее представление о синтаксисе одного файлового компонента. Вы можете прочитать об однофайловых компонентах здесь.

Загрузите локально следующий репозиторий:

Https://github.com/caseymorrisus/vue-button-tutorial

После того, как проект выше клонирован / извлечен локально, перейдите в корень проекта и используйте npm для установки зависимостей проекта:

npm install

Руководство

Теперь, когда все установлено, мы должны убедиться, что все работает. Из корня вашего проекта запустите:

npm run dev

Это должно запустить сервер разработки по адресу localhost:8080, который можно открыть в любом браузере. Я предпочитаю Google Chrome, так как у него есть отличное расширение Vue.js devtools. Если вы откроете src/App.vue, вы увидите, что в настоящее время загружен только компонент заголовка, это не весело! Начнем с определения простого шаблона для нашего компонента Button. Откройте src/components/Button/Button.vue и внесите следующие изменения:

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

Структура приложения

По умолчанию для импорта компонента вам необходимо указать его URL-адрес относительно текущего файла. Для небольшого приложения это не кажется проблемой, но может быстро раздражать в больших приложениях с более сложной структурой каталогов. Чтобы обойти эту проблему, я установил псевдоним WebPack, указывающий на наш каталог src/components. Это позволяет нам игнорировать относительное расположение импортируемого каталога. Я также продолжаю и добавляю файл index.js в каждый из наших каталогов компонентов, чтобы сократить наш импорт.

Это позволит нам импортировать такие компоненты:

Псевдоним WebPack, который я использую, чтобы разрешить мне использовать Components, находится в webpack.config.js и выглядит так:

Вам может быть интересно, почему я даю каждому компоненту отдельный каталог. Я делаю это, чтобы дать мне место для хранения файлов, связанных с компонентом. Это могут быть изображения, используемые в компоненте, или дочерние компоненты, которые будут использоваться только определенным компонентом. (Например, компонент Slider имеет компоненты Slide).

Содержание кнопки

Компонент Button еще нужно добавить в наше представление. Откройте App.vue и импортируйте его так:

Компонент по-прежнему должен быть локально зарегистрирован, прежде чем его можно будет использовать. Измените объект компонентов для компонента App, чтобы включить компонент Button:

Мы даем нашему Button компоненту настраиваемое имя тега v-button, чтобы он не конфликтовал с зарезервированными HTML-элементами, как я сделал и с компонентом Header. В этом нет необходимости, если имя компонента не является зарезервированным элементом HTML.

Наконец, мы можем добавить компонент Button в наш шаблон:

Это должно добавить на страницу элемент кнопки с текстом Кнопка. Текстовое содержимое поступает из резервного содержимого, определенного в компоненте Button. Резервное содержимое определяется путем помещения содержимого между тегами <slot> для компонента. Подробнее о слотах и ​​резервном контенте можно прочитать здесь.

Давайте добавим наш собственный контент в компонент Button:

Это должно изменить содержимое кнопки с «Button» на «Custom». Вы не ограничены строками / текстовым содержимым. Любой контент, вставленный между тегами компонентов, будет вставлен в слот. Например, вы можете использовать значок изображения, а не текст, как это (на самом деле не добавляйте это):

Добавление интерактивности / событий с помощью реквизита

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

Откройте Button.vue, пока мы только изменили шаблон. Чтобы наш родительский компонент мог отправлять метод нашему Button компоненту, нам нужно определить onClick опору:

В приведенном выше примере мы задаем нашему Button компоненту значение onClick. Мы говорим Vue проверить переданное значение с помощью свойства type и передать ему значение Function. Это приведет к тому, что Vue выдаст полезную ошибку в вашей среде разработки, если задано значение другого типа. Мы также говорим Vue, что эта опора всегда должна существовать с использованием required в качестве компонента кнопки без события щелчка, что довольно бесполезно. Вы можете узнать больше о проверке свойств и значениях по умолчанию здесь.

Привязать событие клика к DOM

Наш компонент по-прежнему не реагирует на взаимодействие с пользователем, нам нужно привязать метод onClick, который передается как опора. Для этого мы будем использовать v-on (подробнее), чтобы привязать событие к желаемому элементу DOM. Мы будем использовать сокращение @click, то же самое, что набрать v-bind:click, о котором можно прочитать здесь.

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

Передача метода от родительского к дочернему компоненту

Откройте компонент App, расположенный по адресу src/App.vue, и создайте метод consoleClick, который записывает строку в консоль (дополнительная информация о методах):

Метод consoleClick, созданный в нашем App компоненте, теперь готов к передаче в качестве значения для свойства onClick для компонента Button. Это можно сделать следующим образом:

Ключ здесь :onClick, что эквивалентно v-bind:onClick (сокращение), которое позволяет нам привязать выражение JavaScript к нашей onClick опоре. В этом случае мы передаем функцию (и проверяем ее с помощью проверки!), Но она также может быть числом, строкой, массивом, логическим значением или объектом.

Если вы нажмете кнопку и посмотрите на консоль, вы увидите, что строка Button clicked была зарегистрирована. Замечательно, мы успешно передали метод родительского компонента дочернему компоненту и отложили вызов этого метода до тех пор, пока дочерний компонент не будет нажат.

Несколько экземпляров компонента

Компоненты не доставляют большого удовольствия, если они используются только один раз, давайте создадим еще один экземпляр нашего нового компонента Button. Давайте также передадим другой метод новому экземпляру Button. Во-первых, давайте добавим новый метод к нашему App компоненту, alertClick, который будет создавать предупреждение при нажатии кнопки.

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

Обе кнопки должны работать, первая отправляет сообщение в консоль разработки, а вторая - то же сообщение. Легкий!

Бесплатная функциональность

Поскольку мы использовали собственный элемент кнопки в качестве корневого элемента нашего компонента Button, мы получаем некоторую бесплатную функциональность. Если бы мы использовали div в качестве корневого элемента, следующее не сработало бы. Использование встроенного элемента кнопки также имеет дополнительное преимущество в виде семантически правильного (подробнее). Отредактируйте шаблон для компонента App, чтобы передать свойство disabled одной из кнопок.

Мы можем использовать сокращенный синтаксис при передаче истинного значения для свойства, которое ожидает логическое значение. Передача disabled нашему компоненту аналогична передаче :disabled="true". Обратите внимание, что мы используем сокращенный синтаксис v-bind: для отправки значения true. Без него Vue будет думать, что вы отправляете строку со значением true, или "true". Это нормально, пока вы не попытаетесь отправить disabled="false", который отключит кнопку, потому что строка со значением false не является ложным значением. Он вернет истину.

Заключение

Теперь у нас есть красивый, многоразовый Button компонент, который при желании можно было бы расширить. Может показаться, что для этого потребовалось много работы, но мы рассмотрели много важных тем, на которые вы можете опираться в будущем. Ищите больше статей в будущем, я планирую продолжить серию до того момента, когда мы вместе создадим небольшой UI-фреймворк.

Если вы найдете что-нибудь полезное в этой статье, для меня это будет много значить, если вы нажмете 💚 и поделитесь с друзьями!