[Перевод] 5 библиотек для Vue.js, без которых мне не обойтись

Опытные разработчики знают о том, что иногда, пытаясь сэкономить время и решить какие-то задачи своего проекта с помощью пакета, созданного кем-то другим, можно, в итоге, потратить больше времени, чем было сэкономлено. Библиотеки, жёстко регламентирующие реализацию неких механизмов и не позволяющие решать с их помощью необычные задачи, выходящие за рамки того, что кажется правильным их авторам, заставляют нас, буквально сразу же после их установки, жалеть о том, что мы вообще решили их попробовать.

ju2nn72rk4t95pnhetbq5ezfaw4.jpeg

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

1. Скрытие элементов по щелчку за их пределами


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

Это — библиотека vue-clickaway.

b577a5ceaa77692dc74f4da6ede2cc8c.gif
Скрытие элемента по щелчку за его пределами

▍Использование vue-clickaway


Обычно я подключаю этот пакет в main.js, что позволяет пользоваться им во всём приложении. Если же он применяется лишь на одной-двух страницах, то вы, скорее всего, решите импортировать его лишь там, где он нужен.

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

directives: { onClickaway }


Но не так:

components: { onClickaway }


Вот как сделать директиву доступной на глобальном уровне (в main.js):

import { directive as onClickaway } from 'vue-clickaway'
Vue.directive('on-clickaway', onClickaway)


Вот как пользоваться этой директивой в шаблоне (тут приведён, для простоты, сокращённый вариант кода):


    {{ selectedYear }}
    Open


Представим, что у меня имеется полноценное поле для выбора элементов, включая список элементов

  • (он в коде не показан). Вышеописанная кнопка используется для вывода списка на экран, а когда я щёлкаю за пределами этого элемента, я тем самым вызываю метод, который закрывает список. Это позволяет сформировать гораздо более удачный 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.

    1ff3d262ee8e814fafcb4fc99f7e7235.gif
    Уведомление, реализованное с помощью 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: использование уведомлений в компоненте (в шаблоне)

    
    


    Вот — метод, вызываемый при щелчке по кнопке:

    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.

    9979f84e092f061a8630ceaed71c492a.png


    Пример использования vue-good-table

    Я уверен в том, что эта библиотека способна решить большинство задач по работе таблицами, встающими перед разработчиком. И её название, «good-table» («хорошая таблица»), это — не просто слова. Это — действительно хорошая библиотека, которая предоставляет нам гораздо больше возможностей, чем можно ожидать.

    ▍Использование vue-good-table


    В следующем примере я привязываю данные :rows к геттеру Vuex, называемому getOrderHistory:

    
    


    Вот описания столбцов таблицы в локальных данных (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 к классам, которые я задал в моём локальном теге