Vue: как воспользоваться jquery-плагинами
несколько простых примеров
Обновлено 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();
}
...