Vue: как воспользоваться jquery-плагинами

несколько простых примеров

Alex Sokolov
4 min readNov 16, 2016

Обновлено 07.01.2018: Пересмотрел свежим взглядом и внёс мелкие правки. Заходите и в Telegram-канал по Vue: https://t.me/vuejs_ru

Для Vue шаблон — всего лишь декларативная привязка к данным, и самостоятельно управлять DOM нам не потребуется. Это замечательно, но если потребовалась какая-то фишка, которая встречалась ранее в виде jQuery-плагина. Как же им воспользоваться?

Начать лучше с поисков, вдруг кто-то уже сделал компонент для такого или компонент-обёртку для плагина. Вот несколько сайтов с подборками для Vue:

Будьте внимательны для какой версии Vue создавался компонент — возможно компоненты для Vue 1.х не заработают с Vue 2.х.

Но что же делать, если компонента нет, или автор обещает доработать функциональность когда-нибудь потом, а возможность уже нужна? Вариантов два: написать собственный компонент, который реализует необходимое, или воспользоваться каким-нибудь плагином.

Плагины только для отображения данных

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

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

// <template>
<div id="plugin-container"></div>
// <script>
import $ from 'jquery'; // подключаем jQuery
import 'whateverplugin'; // подключаем сам плагин
...
export default {
data () {
return {
options: [...]
};
},
...
mounted () {
$('#plugin-container').whateverplugin({
...
// передаем в плагин данные из свойства Vue
options: this.options
...
});
}
}

Готово! Но что если нужна обратная связь от плагина?

Плагины, работающие с данными

Примером таких плагинов могут быть плагины-обёртки для полей. Кроме “красивого” отображения вместо стандартного поля нужно чтобы изменения в нём должно отражались и на данных Vue.

Возьмём например поле, которое связано через v-model. Случается, что плагин реализован как подобает, все свои изменения синхронизирует с полем, отрабатывают нужные события, а Vue эти изменения замечает и тоже обновляет значение у себя.

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

Summernote

Например, на текстовое поле хочется добавить простой текстовый редактор. В шаблоне уже есть текстовое поле, оно связано с моделью и имеет id (к которому будем подцеплять плагин). В секции mounted компонента просто инициализируем плагин:

// <template>
<textarea id="editor" v-model="text"></textarea>
// <script>
import $ from 'jquery'; // ... jquery
import 'summernote'; // ... сам плагин
...
mounted: function(){
$('#editor').summernote({
// ... настройки плагина
});
}

Сам плагин будет работать, но вот любые изменения в текстовом поле никак не будут отражены в свойстве text в данных. Каким же образом сохранять новые данные? Summernote при инициализации можно указать коллбэки для различных событий, в частности onChange, вызываемый при изменениях содержимого редактора. Это нам и нужно, добавим в этот коллбэк сохранение данных обратно во Vue:

mounted: function() {
var $vm = this; // сохраняем ссылку на Vue
$('#editor').summernote({
// ... другие настройки плагина
callbacks: {
onChange: function(contents) {
$vm.text = contents; // сохраняем новые данные
}
}
});
}

Запомните, так как мы для коллбэка onChange указываем обычную функцию, а она создаёт свой собственный контекст, то this внутри уже указывает на Vue. Чтобы это исправить — заранее сохраняем ссылку на Vue в переменную $vm.

Selectize.js

Разберём ещё один аналогичный пример, если у нас есть возможность использования ES6 возможностей (в частности, стрелочные функции). Это поможет уменьшить код и избавит от необходимости сохранять ссылку на Vue:

// <template>
<input id="town-picker" v-model="field" />
// <script>
mounted () {
$('#town-picker').selectize({
// ... настройки плагина
onChange: (value) => {
this.field = value; // сохраняем значение во Vue
}
});
}

Другой приятной возможностью при реализации обёрток над компонентами является возможность отказаться от использования селекторов по ID или имени класса. Во Vue это можно реализовать с помощью ref, который предоставляет ссылку на DOM-элемент.

// <template>
<input ref="town" v-model="field" /> // используем ref
// <script>
mounted () {
$(this.$refs.town).selectize({ // получаем DOM-элемент по имени
...
});
}

P.S.: Если плагин предоставляет методы для уничтожения собственного экземпляра (где он может удалять глобальные обработчики или подчищать за собой хранимые где-либо данные), то стоит добавить вызов таких методов в секции beforeDestroy компонента. К примеру, у Selectize.js есть метод destroy:

...
beforeDestroy () {
$('#town-picker')[0].selectize.destroy();
}
...

--

--