├── .gitignore ├── index.d.ts ├── package.json ├── LICENSE.md ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | 3 | declare module "vue-plugin-load-script"; 4 | 5 | declare module "vue/types/vue" { 6 | interface Vue { 7 | $loadScript: (src: string) => Promise; 8 | $unloadScript: (src: string) => Promise; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-plugin-load-script", 3 | "version": "1.3.6", 4 | "description": "A Vue plugin for injecting remote scripts", 5 | "main": "index.js", 6 | "repository": "https://github.com/tserkov/vue-plugin-load-script", 7 | "author": "tserkov ", 8 | "license": "MIT", 9 | "typings": "./index.d.ts", 10 | "devDependencies": { 11 | "vue": "<3.0.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 James Churchard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | const LoadScript = { 3 | install: function (Vue) { 4 | Vue.loadScript = Vue.prototype.$loadScript = function (src) { // eslint-disable-line no-param-reassign 5 | return new Promise(function (resolve, reject) { 6 | let shouldAppend = false; 7 | let el = document.querySelector('script[src="' + src + '"]'); 8 | if (!el) { 9 | el = document.createElement('script'); 10 | el.type = 'text/javascript'; 11 | el.async = true; 12 | el.src = src; 13 | shouldAppend = true; 14 | } 15 | else if (el.hasAttribute('data-loaded')) { 16 | resolve(el); 17 | return; 18 | } 19 | 20 | el.addEventListener('error', reject); 21 | el.addEventListener('abort', reject); 22 | el.addEventListener('load', function loadScriptHandler() { 23 | el.setAttribute('data-loaded', true); 24 | resolve(el); 25 | }); 26 | 27 | if (shouldAppend) document.head.appendChild(el); 28 | }); 29 | }; 30 | 31 | Vue.unloadScript = Vue.prototype.$unloadScript = function (src) { // eslint-disable-line no-param-reassign 32 | return new Promise(function (resolve, reject) { 33 | const el = document.querySelector('script[src="' + src + '"]'); 34 | 35 | if (!el) { 36 | reject(); 37 | return; 38 | } 39 | 40 | document.head.removeChild(el); 41 | 42 | resolve(); 43 | }); 44 | }; 45 | }, 46 | }; 47 | 48 | export default LoadScript; 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-plugin-load-script [![license](https://img.shields.io/github/license/tserkov/vue-plugin-load-script.svg)]() 2 | A plugin for injecting remote scripts. 3 | 4 | Compatible with Vue 2. 5 | 6 | For Vue 3, see [the vue3 branch](/tserkov/vue-plugin-load-script/tree/vue3). 7 | 8 | ## Install 9 | 10 | ``` bash 11 | # npm 12 | npm install --save vue-plugin-load-script@^1.x.x 13 | ``` 14 | 15 | ``` bash 16 | # yarn 17 | yarn add vue-plugin-load-script@^1.x.x 18 | ``` 19 | 20 | ## Use 21 | 22 | ### With Vue 23 | ```javascript 24 | // In main.js 25 | import LoadScript from 'vue-plugin-load-script'; 26 | 27 | Vue.use(LoadScript); 28 | ``` 29 | 30 | ### With Nuxt 31 | ```javascript 32 | // @/plugins/load-script.js 33 | import Vue from 'vue'; 34 | import LoadScript from 'vue-plugin-load-script'; 35 | Vue.use(LoadScript); 36 | ``` 37 | 38 | ```javascript 39 | // @/nuxt.config.js 40 | //... 41 | plugins: [ 42 | { src: '@/plugins/load-script.js' }, 43 | ], 44 | //... 45 | build: { 46 | transpile: ['vue-plugin-load-script'], 47 | }, 48 | //... 49 | ``` 50 | The `build.transpile` option is required since this plugin is exported as an ES6 module. 51 | 52 | ### Usage 53 | 54 | ```javascript 55 | // As a global method 56 | Vue.loadScript("https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY") 57 | .then(() => { 58 | // Script is loaded, do something 59 | }) 60 | .catch(() => { 61 | // Failed to fetch script 62 | }); 63 | 64 | // As an instance method inside a component 65 | this.$loadScript("https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY") 66 | .then(() => { 67 | // Script is loaded, do something 68 | }) 69 | .catch(() => { 70 | // Failed to fetch script 71 | }); 72 | ``` 73 | Once loaded, the script can be accessed by their usual name in the global scope, as if the script were included in the page's ``. 74 | 75 | If you are using a linter to check your code, it may warn on an undefined variable. You will need to instruct your linter to ignore this variable or function. [See here for ESLint instructions](https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals). If you are unable to resolve this in your linter, try prefixing the loaded library's variable/function name with `window.`. 76 | 77 | :zap: __New in 1.2!__ 78 | If you'd like to remove (unload) the script at any point, then call the companion method `$unloadScript` __with the same URL__. 79 | 80 | ```javascript 81 | // As a global method 82 | Vue.unloadScript("https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY") 83 | .then(() => { 84 | // Script was unloaded successfully 85 | }) 86 | .catch(() => { 87 | // Script couldn't be found to unload; make sure it was loaded and that you passed the same URL 88 | }); 89 | 90 | // As an instance method inside a component 91 | this.$unloadScript("https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY") 92 | .then(() => { 93 | // Script was unloaded successfully 94 | }) 95 | .catch(() => { 96 | // Script couldn't be found to unload; make sure it was loaded and that you passed the same URL 97 | }); 98 | ``` 99 | In most situations, you can just call `Vue.unloadScript`/`this.$unloadScript` and ignore the returned promise. 100 | --------------------------------------------------------------------------------