Lodash, Moment, Axios, Async … это полезные библиотеки JavaScript, которые вы захотите использовать во многих своих приложениях Vue.js.
Но по мере роста вашего проекта вы будете разделять код на отдельные файловые компоненты и файлы модулей. Вы также можете запустить свое приложение в разных средах, чтобы разрешить рендеринг сервера.
Если вы не найдете простой и надежный способ включения этих библиотек JavaScript в ваши компоненты и файлы модулей, это будет неприятно!
Как не включать библиотеку в проект Vue.js
Глобальная переменная
Наивный способ добавить библиотеку в ваш проект — сделать ее глобальной переменной, прикрепив ее к window
объекту:
entry.js
JavaScript
xxxxxxxxxx
1
window._ = require('lodash');
MyComponent.vue
JavaScript
xxxxxxxxxx
1
export default {
2
created() {
3
console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..');
4
}
5
}
Случай с оконными переменными является длинным, но, в данном случае, они не работают с рендерингом сервера. Когда приложение запускается на сервере, window
объект будет неопределенным, поэтому попытка получить доступ к свойству приведет к ошибке.
Импорт в каждый файл
Другой второстепенный метод — импортировать библиотеку в каждый файл:
MyComponent.vue
JavaScript
xxxxxxxxxx
1
import _ from 'lodash';
2
export default {
4
created() {
5
console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
6
}
7
}
Это работает, но это не очень СУХОЙ, и это в основном просто боль: вы должны помнить, чтобы импортировать его в каждый файл, и удалить его снова, если вы перестанете использовать его в этом файле. И если вы не настроите свой инструмент сборки правильно, вы можете получить несколько копий одной и той же библиотеки в вашей сборке.
Лучший путь
Самый чистый и надежный способ использования библиотеки JavaScript в проекте Vue - это передать ее в свойство объекта-прототипа Vue. Давайте сделаем это, чтобы добавить библиотеку даты и времени Moment в наш проект:
entry.js
JavaScript
xxxxxxxxxx
1
import moment from 'moment';
2
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
Поскольку все компоненты наследуют свои методы от объекта-прототипа Vue, это сделает Moment автоматически доступным для всех без исключения глобальных переменных или чего-либо для импорта вручную. Доступ к нему можно получить в любом экземпляре / компоненте из this.$moment
:
MyNewComponent.vue
JavaScript
xxxxxxxxxx
1
export default {
2
created() {
3
console.log('The time is ' . this.$moment().format("HH:mm"));
4
}
5
}
Давайте потратим время, чтобы понять, как это работает.
Object.defineProperty
Обычно мы устанавливаем свойство объекта следующим образом:
JavaScript
xxxxxxxxxx
1
Vue.prototype.$moment = moment;
Вы можете сделать это здесь, но, используя
Object.defineProperty
вместо этого, мы можем определить наше свойство с помощью
дескриптора . Дескриптор позволяет нам устанавливать некоторые низкоуровневые детали, такие как, является ли наше свойство доступным для записи и отображается ли оно во время перечисления в
for
цикле и многое другое.
Обычно мы не беспокоимся об этом в нашем повседневном JavaScript, потому что в 99% случаев нам не нужен такой уровень детализации при назначении свойств. Но здесь это дает нам явное преимущество: свойства, созданные с помощью дескриптора, по умолчанию доступны только для чтения .
Это означает, что какой-то разработчик, лишенный кофе (возможно, вы), не сможет сделать что-то глупое в компоненте и сломать все:
JavaScript
xxxxxxxxxx
1
this.$http = 'Assign some random thing to the instance method';
2
this.$http.get('/'); // TypeError: this.$http.get is not a function
Вместо этого наш метод экземпляра только для чтения защищает нашу библиотеку, и если вы попытаетесь перезаписать ее, вы получите «TypeError: Невозможно назначить свойство только для чтения».
$
Вы заметите, что мы проксируем нашу библиотеку на имя свойства с префиксом доллара «$». Вы , вероятно , также видели другие свойства и методы , такие как $refs
, $on
, $mount
и т.д., которые имеют этот префикс тоже.
Хотя это и не обязательно, префикс добавляется в свойства, чтобы напомнить разработчикам, лишенным кофе (и вам снова), что это общедоступное свойство или метод API, которые вы можете использовать, в отличие от других свойств экземпляра, которые, вероятно, предназначены только для Vue. внутреннее использование.
Будучи языком на основе прототипов, в JavaScript нет (реальных) классов, поэтому в нем нет «закрытых» и «открытых» переменных или «статических» методов. Это соглашение - мягкая замена, которой, я думаю, стоит следовать.
этот
Вы также заметите, что использование используемой вами библиотеки, this.libraryName
вероятно, неудивительно, поскольку теперь это метод экземпляра.
Однако одним из следствий этого является то, что, в отличие от глобальной переменной, вы должны убедиться, что вы используете правильную область при использовании вашей библиотеки. Внутри методов обратного вызова, вы не можете получить доступ к тому, this
что ваша библиотека обитает.
Полные обратные вызовы стрелок являются хорошим решением, чтобы убедиться, что вы остаетесь в нужной области:
JavaScript
xxxxxxxxxx
1
this.$http.get('/').then(res => {
2
if (res.status !== 200) {
3
this.$http.get('/') // etc
4
// Only works in a fat arrow callback.
5
}
6
});
Почему бы не сделать это плагином?
Если вы планируете использовать библиотеку во многих проектах Vue или хотите поделиться ею со всем миром, вы можете встроить ее в свой собственный плагин!
Плагин абстрагирует сложность и позволяет вам просто сделать следующее в проекте, чтобы добавить выбранную вами библиотеку:
JavaScript
xxxxxxxxxx
1
import MyLibraryPlugin from 'my-library-plugin';
2
Vue.use(MyLibraryPlugin);
С помощью этих двух строк мы можем использовать библиотеку в любом компоненте так же, как мы можем использовать Vue Router, Vuex и другие плагины, которые используют Vue.use
.
Написание плагина
Во-первых, создайте файл для вашего плагина. В этом примере я создам плагин, который добавляет Axios ко всем вашим экземплярам и компонентам Vue, поэтому я назову файл axios.js .
Главное, чтобы понять, что плагин должен предоставлять install
метод, который принимает конструктор Vue в качестве первого аргумента:
axios.js
JavaScript
xxxxxxxxxx
1
export default {
2
install: function(Vue) {
3
// Do stuff
4
}
5
}
Теперь мы можем использовать наш предыдущий метод для добавления библиотеки к объекту-прототипу:
axios.js
JavaScript
xxxxxxxxxx
1
import axios from 'axios';
2
export default {
4
install: function(Vue,) {
5
Object.defineProperty(Vue.prototype, '$http', { value: axios });
6
}
7
}
Метод use
instance - это все, что нам сейчас нужно, чтобы добавить нашу библиотеку в проект. Например, теперь мы можем добавить библиотеку Axios так же просто, как это:
entry.js
JavaScript
xxxxxxxxxx
1
import AxiosPlugin from './axios.js';
2
Vue.use(AxiosPlugin);
3
new Vue({
5
created() {
6
console.log(this.$http ? 'Axios works!' : 'Uh oh..');
7
}
8
})
Бонус: плагин Необязательные аргументы
Ваш метод установки плагина может принимать необязательные аргументы. Некоторым разработчикам может не понравиться вызов метода экземпляра Axios, $http
поскольку Vue Resource обычно дают это имя, поэтому давайте воспользуемся необязательным аргументом, чтобы они могли изменить его на любое другое:
axios.js
JavaScript
xxxxxxxxxx
1
import axios from 'axios';
2
export default {
4
install: function(Vue, name = '$http') {
5
Object.defineProperty(Vue.prototype, name, { value: axios });
6
}
7
}
entry.js
JavaScript
1
import AxiosPlugin from './axios.js';
2
Vue.use(AxiosPlugin, '$axios');
3
new Vue({
5
created() {
6
console.log(this.$axios ? 'Axios works!' : 'Uh oh..');
7
}
8
})