Love Frontend
Сообщество
фронтенд разработчиков
EN

Как сделать плагин для Vue

Дата публикации: 07.07.2018
Как сделать плагин для vue vuejs

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

В качестве практического примера в статье будет использоваться плагин для добавления модификаторов к классам: vue-mods-names

Подключение плагина осуществляется с помощью глобального метода use(). При этом в вашем плагине просто должен быть метод install().

Это глобальное подключение плагина в приложение.

import Vue from 'vue'
import yourPlugin from './folder/yourPlugin'
Vue.use(yourPlugin)

Это содержимое самого плагина. Как видите, чтобы ваш код работал как плагин Vue, главное что вам нужно сделать — это добавить метод install, который принимает Vue instance и если вам нужно дополнительные опции для работы плагина.

export default {
install (Vue) {
...
}
}

Теперь рассмотрим что же в этот момент происходит за кулисами Vue. Код, отвечающий за метод use в самом фрэймворке находится в папке

/core/global-api в файле use.js

     export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins ||
(this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
...

Во-первых, мы видим, что константа installedPlugins (установленные плагины) берёт свойство _installedPlugins из текущего экземпляра Vue, то есть от туда, где мы вызвали метод use. И если у этого экземпляра нет установленных плагинов (т.е. ни один плагин до этого не устанавливался), то код просто вернёт в константу пустой массив. Сейчас я просто описал как работает строка кода:

     const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) 

Во-вторых, с помощью метода indexOf, проверяется есть ли в массиве installedPlugins плагин, который мы передали в метод use. Если он есть то возвращается this и ничего дальше не выполняется естественно. А если плагина нету в списке, то дальше идёт как раз применение вашего плагина и добавление его в список. Эта проверка позволяет нам не переживать о многократной установке плагинов. Даже если вы в разных местах своего приложения будете пытаться установить один и тот же плагин с помощью vue.use(), то благодаря этой проверке он установится только один раз. Вот как эта функциональность описывается в официальной документации Vue:

Vue.use автоматически предохранит вас от многократной регистрации одного и того же плагина. Вызов Vue.use для одного и того же плагина несколько раз приведёт лишь к однократной его установке.

Теперь рассмотрим что же происходит дальше, когда нашего плагина ещё не было в списке установленных плагинов.

     // additional parameters
const args = toArray(arguments, 1)
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this

Пусть вас не пугает вспомогательная функция toArray(), она используется для конвертации массивоподобного объекта в настоящий массив ( Convert an Array-like object to a real Array) и лежит в папке shared/util.js. Это нужно, потому что arguments как раз является объектом подобным массиву.

После чего, вставляется перед переданными аргументами (то есть перед нашим плагином и его опциями (если они есть) ссылка на текущий instance. Теперь если мы вызываем метод use у VueA instance, то мы имеем массив args = [VueA, plugin, options] (первый аргумент ссылается на экземпляр у которого был вызван метод use).

Потом, с помощью метода apply в коде вызывается метод install нашего плагина и передаётся ему массив собранных аргументов. Так как в данном случае передаётся в apply первым параметром наш plugin, то при вызове install ключевое слово this будет указывать на него же.

Данная конструкция позволяет нам правильно определить то место на что будет ссылаться ключевое слово this при выполнении вашего плагина. Explicit Binding или явная привязка (по книге Kyle Simpson). И также передать экземпляр Vue. Теперь в вашем плагине this указывает на текущий компонент (при глобальной установке на каждый компонент) а Vue (первый аргумент) на экземпляр у которого вызывается метод use. И теперь мы можем например создавать миксины или директивы: Vue.mixin, Vue.directive, а внутри this будет указывать на каждый компонент.

Обратите внимание, что метод use проверяет является ли свойство install вашего плагина функцией, если да, то вызываем её. Но то же самое сработает если мы передадим просто функцию не обёрнутую в объект со свойством install.

В завершении код из фрэймворка добавляет в конец массива с установленными плагинами наш плагин и теперь благодаря проверки сверху, Vue больше не будет применять ваш плагин с помощью apply. Он сделает это только один раз.

Оставьте свой e-mail чтобы получать уведомления о свежих статьях.