Я использую Webpack и VueJs 2. Я хочу использовать в своем компоненте стороннюю библиотеку javascript, например такую:
<script async defer src = "https://apis.google.com/js/api.js" ... ></script>
Я нашел статью здесь о том, как это сделать для пакетов npm, но у меня это не работает, поскольку эта библиотека недоступна как пакет npm.
Я не могу загрузить файл локально и использовать его, так как библиотека может измениться и перестать работать. Поэтому он должен загружаться по ссылке каждый раз, когда страница загружается браузером.
Я нашел одно возможное решение здесь, но это в основном взлом (измените dom, чтобы добавить элемент script после загрузки документа)
Я считаю, что для этой проблемы должно быть простое хорошее практическое решение, поскольку я предполагаю, что это обычный вариант использования.
Обновлять: Если я помещу сценарий в теги заголовка в моем индексном файле, он будет загружен для всех компонентов. По соображениям производительности я бы хотел, чтобы он загружался только для определенного компонента.
Почему бы вам не поместить тег сценария в <head> файла index.html?
@ LoïcMonard см. Обновление
если вы не хотите включать его в свой индексный файл, вы все равно можете включить его в один компонент, поэтому он будет загружен только тогда, когда этот компонент загружен
@samayo, можешь ли ты привести пример, как это сделать?
Это настолько хорошо, насколько это возможно: stackoverflow.com/a/49331651/1850609 - Различия, о которых вы говорите («Я бы хотел, чтобы он загружался только для определенного компонента».), технически невозможны. Эти внешние скрипты обычно модифицируют (добавляют переменные) объект window. Вы не можете изменить его с помощью ООН, не зная внутренней части скрипта (так что общего решения этой проблемы нет). Если бы была достаточно хорошая идея, даже если бы загрузчика не было, я бы реализовал ее сам (ваш запрос очень распространен!), Но, к сожалению, нет хорошего универсального решения .


Насколько я знаю, вы не можете использовать что-то лучше, чем динамическое добавление тега script в заголовок вашей страницы. Однако вы можете создать небольшой плагин, который справится с этим за вас и запускает загрузку скрипта только в тех компонентах, которые вам нужны, и только один раз.
Начнем с самого плагина:
import Vue from 'vue'
const scriptLoader = {
loaded: [],
load (src) {
if (this.loaded.indexOf(src) !== -1) {
return
}
this.loaded.push(src)
if (document) {
const script = document.createElement('script')
script.setAttribute('src', src)
document.head.appendChild(script)
}
}
}
Vue.use({
install () {
Vue.prototype.$scriptLoader = scriptLoader
}
})
Как видите, вы создаете объект scriptLoader, который содержит какой-то объект кэша loaded, который будет помнить, какой сценарий вы уже загрузили в какой-то момент своего приложения. Он также содержит метод load(), который будет обрабатывать добавление сценария в вашу голову.
Условие if (document) здесь, в случае, если вы будете отображать свое приложение на стороне сервера, document не будет существовать.
Затем вы можете загрузить свой скрипт в любой из ваших компонентов при создании с помощью ловушки created:
export default {
...
created () {
this.$scriptLoader.load('https://apis.google.com/js/api.js')
}
}
Это самый чистый способ обработки такого сценария ... Надеюсь, это поможет ...
Хорошо, нашел решение, удовлетворяющее всем требованиям.
Добавьте скрипт в index.html с директивой v-if
<script v-if = "loadGoogleAPI" async defer src = "https://apis.google.com/js/api.js" ... ></script>
Внутри файла компонента (.vue), если вы хотите, чтобы скрипт загружался, установите флаг true:
<script>
export default {
...
loadGoogleAPI: true,
data() {
...
}
};
</script>
Если script с v-if находится вне экземпляра Vue, v-if вообще не действует.
Даже если v-if действительно работал, удаление script тоже не повлияет на уже загруженный код. Удаление <script>не выгружает свой код.
@acdcjunior Это хороший момент, но, к счастью, мне не нужно выгружать скрипт. Если бы мне понадобился один обходной путь, я бы сделал многостраничное приложение vue
Тогда другой вопрос / ответ, который я указал, делают то же самое.
Почему бы вам просто не включить скрипт, как показано в вашем примере, и создать его экземпляр, если он должен быть .. внутри хуков created / method?