Опытные разработчики знают о том, что иногда, пытаясь сэкономить время и решить какие-то задачи своего проекта с помощью пакета, созданного кем-то другим, можно, в итоге, потратить больше времени, чем было сэкономлено. Библиотеки, жёстко регламентирующие реализацию неких механизмов и не позволяющие решать с их помощью необычные задачи, выходящие за рамки того, что кажется правильным их авторам, заставляют нас, буквально сразу же после их установки, жалеть о том, что мы вообще решили их попробовать.
Хотя со мной такое случалось довольно часто, у меня, всё же, есть небольшой список любимых библиотек, которые я использовал во множестве проектов, и которые за долгое время доказали свою крайнюю полезность. Я испытал множество подходов к решению тех задач, которые решают эти библиотеки. На мой выбор повлияло удобство работы с библиотекой, разнообразие её возможностей, хороший внешний вид того, что получается при её применении. В итоге у меня и появился тот список, которым я хочу с вами поделиться.
1. Скрытие элементов по щелчку за их пределами
Иногда бывает так, что нужно вызвать событие, когда пользователь щёлкнет мышью за пределами некоего элемента. Чаще всего так нужно поступить тогда, когда требуется, чтобы таким образом можно было бы закрыть выпадающий список или диалоговое окно. Для реализации такого поведения существует один пакет, который я использую практически в каждом разрабатываемом мной приложении.
Это — библиотека vue-clickaway.
Скрытие элемента по щелчку за его пределами
▍Использование vue-clickaway
Обычно я подключаю этот пакет в main.js
, что позволяет пользоваться им во всём приложении. Если же он применяется лишь на одной-двух страницах, то вы, скорее всего, решите импортировать его лишь там, где он нужен.
При его индивидуальном импорте помните о том, что вы импортируете директиву, а не компонент. То есть, правильно будет поступить так:
directives: { onClickaway }
Но не так:
components: { onClickaway }
Вот как сделать директиву доступной на глобальном уровне (в main.js
):
import { directive as onClickaway } from 'vue-clickaway'
Vue.directive('on-clickaway', onClickaway)
Вот как пользоваться этой директивой в шаблоне (тут приведён, для простоты, сокращённый вариант кода):
<button
v-on-clickaway="closeYearSelect"
class="select_option gray"
@click="toggleYearSelect"
>
<span class="txt">{{ selectedYear }}</span>
<span class="arrow blind">Open</span>
</button>
Представим, что у меня имеется полноценное поле для выбора элементов, включая список элементов <li>
(он в коде не показан). Вышеописанная кнопка используется для вывода списка на экран, а когда я щёлкаю за пределами этого элемента, я тем самым вызываю метод, который закрывает список. Это позволяет сформировать гораздо более удачный UX, чем когда пользователь всегда будет вынужден щёлкать по кнопке закрытия, расположенной в углу элемента. Этот функционал мы получаем, добавляя к описанию кнопки следующую конструкцию:
v-on-clickaway="closeMethodName"
Обратите внимание на то, что vue-clickaway
всегда нужно использовать с методом, который что-то закрывает, а не с методом, который отображает и скрывает элемент. Я имеют в виду то, что метод, подключённый к v-on-clickaway
, должен выглядеть примерно так:
closeMethod() {
this.showSomething = false
}
Но этот метод не должен быть таким:
toggleMethod() {
this.showSomething = !this.showSomething
}
Если используется что-то вроде метода toggleMethod
, то вы, когда будете щёлкать за пределами элемента, будете его открывать и закрывать, вне зависимости от того, где именно щёлкаете. Вам, вероятно, это ни к чему. Поэтому просто используйте с v-on-clickaway
методы, скрывающие элементы.
2. Всплывающие уведомления
Создавать всплывающие уведомления можно с использованием различных инструментов, но я — большой фанат библиотеки vue-toastification.
Уведомление, реализованное с помощью vue-toastification
Она даёт в распоряжение разработчика массу настроек, благодаря которым с её помощью можно реализовывать уведомления, соответствующие самым разным нуждам. Возможности этой библиотеки по стилизации и анимации уведомлений позволяют создавать привлекательные и удобные решения, более качественные, чем можно создать с использованием других пакетов.
▍Использование vue-toastification
Библиотеку vue-toastification
можно использовать разными способами. Подробности об этом ищите в её документации. Так, её можно применять на уровне компонента, на глобальному уровне, или даже вместе с Vuex, в том случае, если уведомления нужно показывать, основываясь на изменениях состояния приложения, или на действиях, связанных с сервером.
Вот пример глобального использования этой библиотеки (в main.js
):
import Toast from "vue-toastification"
// Стили уведомлений
import "vue-toastification/dist/index.css"
Vue.use(Toast, {
transition: "Vue-Toastification__bounce",
maxToasts: 3,
newestOnTop: true,
position: "top-right",
timeout: 2000,
closeOnClick: true,
pauseOnFocusLoss: true,
pauseOnHover: false,
draggable: true,
draggablePercent: 0.7,
showCloseButtonOnHover: false,
hideProgressBar: true,
closeButton: "button",
icon: true,
rtl: false,
})
Стилями уведомлений можно управлять по-отдельности, задавая их в каждом компоненте, но в вышеприведённом случае я сделал стили уведомлений доступными во всём приложении, импортировав их в main.js
. После этого я настроил параметры уведомлений. Это избавило меня от необходимости писать один и тот же код каждый раз, когда мне нужно воспользоваться уведомлением. У библиотеки vue-toastification имеется отличная площадка для экспериментов. На ней можно увидеть результаты воздействия параметров на уведомления и тут же скопировать в свой код то, что нужно. Именно так я поступил и в вышеприведённом примере.
Рассмотрим пару вариантов использования этой библиотеки.
▍Вариант 1: использование уведомлений в компоненте (в шаблоне)
<button @click="showToast">Show toast</button>
Вот — метод, вызываемый при щелчке по кнопке:
methods: {
showToast() {
this.$toast.success("I'm a toast!")
}
}
▍Вариант 2: вывод уведомления при возникновении ошибки (или при успешном выполнении операции) в Vuex
Вот пример кода, демонстрирующий использование this._vm.$toast.error
в Vuex при возникновении ошибки:
async fetchSomeData({ commit }) {
const resource_uri = `/endpoint/url`
try {
await axios.get(resource_uri).then((response) => {
commit(SET_DATA, response.data)
})
} catch (err) {
this._vm.$toast.error('Error message: ' + err.message)
}
}
Изменить тип уведомления можно, просто поменяв имя метода .error
на .success
, .info
или .warning
. А если надо — можно и вовсе это убрать и получить уведомление с настройками, задаваемыми по умолчанию.
Всплывающие уведомления позволяют разработчику выводить некие сведения, основываясь на изменениях состояния приложения, или в том случае, когда происходит непредвиденная ошибка. Это улучшает восприятие приложения пользователем. Всплывающие уведомления дают пользователю более качественную визуальную индикацию событий, чем модальные окна или уродливые alert-окна. Ведь при работе с окном пользователю, чтобы его закрыть, нужно лишний раз щёлкнуть мышью. Пользователи оценят то, что вы даёте им визуальные подсказки относительно того, что что-то идёт не так, избавляя их от необходимости беспомощно смотреть на экран, ожидая некоего события, которое никогда не произойдёт. Кроме того, уведомления полезны и в деле подтверждения успешности выполнения некоих операций.
3. Работа с таблицами
Таблицы — это очень важная часть многих веб-приложений. Если выбрать не очень качественную библиотеку для работы с таблицами, это может принести немало проблем. Я испытал множество подобных библиотек и остановился на vue-good-table.
Пример использования vue-good-table
Я уверен в том, что эта библиотека способна решить большинство задач по работе таблицами, встающими перед разработчиком. И её название, «good-table» («хорошая таблица»), это — не просто слова. Это — действительно хорошая библиотека, которая предоставляет нам гораздо больше возможностей, чем можно ожидать.
▍Использование vue-good-table
В следующем примере я привязываю данные :rows
к геттеру Vuex, называемому getOrderHistory
:
<vue-good-table
class="mx-4"
:columns="columns"
:rows="getOrderHistory"
:search-options="{ enabled: true }"
:pagination-options="{
enabled: true,
mode: 'records',
perPage: 25,
position: 'top',
perPageDropdown: [25, 50, 100],
dropdownAllowAll: false,
setCurrentPage: 2,
nextLabel: 'next',
prevLabel: 'prev',
rowsPerPageLabel: 'Rows per page',
ofLabel: 'of',
pageLabel: 'page', // для режима 'pages'
allLabel: 'All'
}"
>
Вот описания столбцов таблицы в локальных данных (data()
):
columns: [
{
label: 'Order Date',
field: 'orderDtime',
type: 'date',
dateInputFormat: 'yyyy-MM-dd HH:mm:ss',
dateOutputFormat: 'yyyy-MM-dd HH:mm:ss',
tdClass: 'force-text-center resizeFont'
},
{
label: 'Order Number',
field: 'orderGoodsCd',
type: 'text',
tdClass: 'resizeFont'
},
{
label: 'Title',
field: 'orderTitle',
type: 'text',
tdClass: 'resizeFont ellipsis'
},
{
label: 'Price',
field: 'saleAmt',
type: 'number',
formatFn: this.toLocale
},
{
label: 'Edit btn',
field: 'deliveryUpdateYn',
type: 'button',
tdClass: 'force-text-center',
sortable: false
},
]
Здесь label
— это заголовок столбца, выводимый на экране, а field
— это данные, к которым осуществляется привязка в геттере Vuex.
В вышеприведённом примере я использую некоторые возможности vue-good-table по настройке таблиц. Это, например, установка входного и выходного формата дат (это позволяет мне брать полное описание даты и времени с сервера и показывать эти сведения пользователям в более удобном формате). Я, кроме того, использую тут formatFn
для форматирования цены с помощью особого метода, который я назвал toLocale
. Затем я настраиваю внешний вид ячеек таблицы, привязывая tdClass
к классам, которые я задал в моём локальном теге <style>
. Пакет vue-good-table, на самом деле, обладает бесконечными встроенными возможностями по настройке. Эти возможности позволяют создавать таблицы, которые способны подойти для весьма широкого спектра вариантов их применения.
▍Создание собственных шаблонов
Библиотека vue-good-table отлично работает и с шаблонами, созданными программистами самостоятельно. Это значит, что в ячейки таблиц можно легко внедрять кнопки, поля для выбора значений из списка, или что угодно другое. Для того чтобы это сделать, достаточно, пользуясь директивой v-if
, указать место, в котором должно быть расположено что-то особенное. Вот пример добавления кнопки в столбец таблицы.
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field === 'cancelYn' && props.row.cancelYn === 'Y' ">
<BaseButton class="button" @click="showModal">
Cancel Order
</BaseButton>
</span>
</template>
В этом примере я описываю кнопку, которая открывает модальное окно. Она выводится в поле cancelYn
(в столбце) в том случае, если значение соответствующего поля данных равняется Y
.
Для того чтобы добавить в таблицу ещё один собственный столбец, достаточно просто добавить v-else-if
после закрывающего тега конструкции, в которой использовалась директива v-if
(в нашем случае это — тег <span>
). После этого надо описать логику нового столбца. В целом, можно сказать, что библиотека vue-good-table способна помочь в любой ситуации, связанной с выводом таблиц на веб-страницах.
4. Средство для выбора дат
А теперь расскажу о библиотеке, предназначенной для организации выбора дат. Нечто подобное встречается в огромном множестве реально существующих приложений. Библиотек, реализующих этот функционал, существует гораздо больше, чем библиотек для решения других задач, о которых я тут рассказываю. Я, решая эту задачу, регулярно возвращаюсь к библиотеке vue2-datepicker.
Пример использования библиотеки vue2-datepicker
Элементы управления для выбора дат, создаваемые с помощью этой библиотеки, легко поддаются стилизации. Она поддерживает массу настроек, касающихся выбора дат и диапазонов дат. Библиотека позволяет формировать аккуратные и удобные элементы пользовательского интерфейса. Она даже поддерживает средства локализации.
Обратите внимание на то, что хотя соответствующий пакет и называется vue2-datepicker, у вас не должно возникнуть проблем при его использовании в приложениях, основанных на Vue 3 (то же самое касается и других библиотек, рассмотренных в этом материале).
▍Использование vue2-datepicker
Библиотеку можно импортировать в компонент или включить в шаблон.
Вот пример её импорта в компонент:
import DatePicker from 'vue2-datepicker';
// стили
import 'vue2-datepicker/index.css';
Вот как пользоваться ей в шаблоне:
<date-picker
v-model="dateRange"
value-type="format"
range
@clear="resetList"
@input="searchDate"
></date-picker>
Здесь я использую опцию range
, позволяя пользователю выбирать диапазоны дат. Здесь же я, с помощью директивы v-model
, подключаю данные, введённые пользователям, к значению dateRange
. Затем dateRange
может, например, использоваться vue-good-table для настройки вывода данных в таблице. Я, кроме того, использую тут опции событий — @clear
и @input
, применяя их для вызова методов, один из которых сбрасывает таблицу (resetList
), а второй отправляет запрос на сервер (searchDate
). Библиотека vue2-datepicker предлагает нам гораздо больше опций и событий, чем я тут описал. Но тем, о чём я тут рассказал, я пользуюсь чаще всего.
5. Рейтинги
Системы рейтингов можно найти, например, на таких сайтах, как Amazon и Rotten Tomatoes. Возможно, подобными системами вы пользуетесь и не в каждом проекте, но я, на каждом сайте, где это нужно, реализую данную возможность с использованием библиотеки vue-star-rating.
Пример использования библиотеки vue-star-rating
Может показаться, что нечто подобное очень легко создать самостоятельно. Но если вникнуть в детали, то окажется, что разработка такого элемента управления может очень быстро стать гораздо сложнее, чем этого можно ожидать. Рассматриваемая библиотека позволяет использовать собственные SVG-изображения для настройки формы фигур, применяемых при выставлении оценок. Она позволяет настраивать размер элементов, расстояние между ними, их цвет.
Оценку, которую пользователь поставил чему-то с помощью элемента управления из vue-star-rating, можно легко, используя v-model
, передать туда, где планируется её использовать. Оценки можно делать изменяемыми или неизменяемыми, воспользовавшись единственным параметром.
А если окажется, что вам при работе с этой библиотекой понадобится больше возможностей — взгляните на пакет vue-rate-it того же автора.
▍Использование vue-star-rating
Вот как пользоваться этой библиотекой в шаблоне (с опциями):
<star-rating
class="star-rating"
:rating="newReivew.score"
active-color="#FBE116"
:star-size="starSize"
:increment="increment"
:show-rating="showRating"
@rating-selected="setRating"
/>
Вот как импортировать её в компонент:
import StarRating from 'vue-star-rating'
export default {
components: {
StarRating
},
}
Итоги
Мы рассмотрели 5 библиотек для Vue. Надеемся, вы нашли здесь что-то такое, что пригодится вам при разработке ваших проектов.
Какими библиотеками для Vue.js вы пользуетесь чаще всего?
Автор: ru_vds