从CDN加载vue.js脚本,然后从组件vue加载脚本(没有webpack)

时间:2019-04-20 17:47:37

标签: vue.js vuejs2 vue-router

如何从组件中的cdn加载自定义脚本。这样我就可以在加载方法中使用foreach

myScript.abc()

这是通过vue-router加载的。 而且不使用vue-loader或webpack

如何加载我的自定义脚本。
任何指向文档的链接都将有所帮助。

1 个答案:

答案 0 :(得分:1)

这应该做到:

    beforeMount(){
      this.scriptLoader('some/url').then(() => {
        this.a();
      }, error => {
        console.error('Failed to load script', error.target.src)
      })
    },
    methods:{
      a:function(){
         myScript.hello();
      }
      scriptLoader: function(url) {
        return new Promise((resolve, reject) => {
          const existing = document.querySelector('script#someUniqueId');
          if (existing) existing.remove();
          const script = document.createElement('script');
          script.onload = () => {
            resolve();
          };
          script.onerror = e => {
            reject(e);
          };
          script.id = 'someUniqueId';
          script.async = true;
          script.src = url;
          document.head.appendChild(script);
        })
      }
    }

让我们尝试一下...

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#app',
  beforeMount() {
    this.scriptLoader('https://vincentgarreau.com/particles.js/assets/_build/js/lib/particles.js').then(() => {
      this.a();
    }, e => console.error('Failed to load script', e.target.src))
  },
  methods: {
    a: function() {
      particlesJS("particles-js", {
        particles: {
          number: {
            value: 80,
            density: {
              enable: true,
              value_area: 840
            }
          },
          color: {
            value: "#ffffff"
          },
          shape: {
            type: "triangle",
            stroke: {
              width: 0,
              color: "#000000"
            },
            polygon: {
              nb_sides: 42
            },
          },
          opacity: {
            value: 0.42,
            random: false,
            anim: {
              enable: false,
              speed: 1,
              opacity_min: 0.1,
              sync: false
            }
          },
          size: {
            value: 3,
            random: true,
            anim: {
              enable: false,
              speed: 42,
              size_min: 0.1,
              sync: false
            }
          },
          line_linked: {
            enable: true,
            distance: 210,
            color: "#ffffff",
            opacity: 0.42,
            width: 1
          },
          move: {
            enable: true,
            speed: 4.2,
            direction: "none",
            random: true,
            straight: false,
            out_mode: "out",
            bounce: false,
            attract: {
              enable: false,
              rotateX: 600,
              rotateY: 1200
            }
          }
        },
        interactivity: {
          detect_on: "canvas",
          events: {
            onhover: {
              enable: true,
              mode: "repulse"
            },
            onclick: {
              enable: true,
              mode: "push"
            },
            resize: true
          },
          modes: {
            grab: {
              distance: 420,
              line_linked: {
                opacity: 1
              }
            },
            bubble: {
              distance: 420,
              size: 42,
              duration: 2.1,
              opacity: 8.4,
              speed: 3
            },
            repulse: {
              distance: 84,
              duration: 0.84
            },
            push: {
              particles_nb: 4.2
            },
            remove: {
              particles_nb: 2.1
            }
          }
        },
        retina_detect: true
      });
    },
    scriptLoader: function(url) {
      return new Promise((resolve, reject) => {
        const existing = document.querySelector('script#particlesJs');
        if (existing) {
            existing.remove();
        }
        const script = document.createElement('script');
        script.onload = () => {
          resolve();
        };
        script.onerror = e => {
          reject(e);
        }
        script.id = 'particlesJs';
        script.async = true;
        script.src = url;
        document.head.appendChild(script);
      })
    }
  }
})
body {
  margin: 0;
  background-color: #212121;
  min-height: 100vh;
}
#particles-js {
  position: absolute;
  height: 100%;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div id="particles-js"></div>
</div>

有错误:

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#app',
  beforeMount() {
    this.scriptLoader('//some/bogus/link/particles.js').then(() => {
      this.a();
    }, e => console.error('Failed to load resource from', e.target.src))
  },
  methods: {
    a: function() {},
    scriptLoader: function(url) {
      return new Promise((resolve, reject) => {
        const existing = document.querySelector('script#particlesJs');
        if (existing) {
            existing.remove();
        }
        const script = document.createElement('script');
        script.onload = () => {
          resolve();
        };
        script.onerror = e => {
          reject(e);
        }
        script.id = 'particlesJs';
        script.async = true;
        script.src = url;
        document.head.appendChild(script);
      })
    }
  }
})
body {
  margin: 0;
  background-color: #212121;
  min-height: 100vh;
}
#particles-js {
  position: absolute;
  height: 100%;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div id="particles-js"></div>
</div>

注意if (existing) existing.remove();

这可防止多次附加相同的<script>
在许多情况下,如果资源没有过期(或者过期是无关紧要的),那么您可能希望跳过脚本重新加载(如果已附加)。即:if(!existing) { /* append the script */ }

通过删除先前附加的<script>并再次添加它,我们会将到期评估传递给浏览器,然后传递给服务该资源的服务器。

如果资源尚未过期,浏览器将从缓存中提供资源,而无需向服务器发出新请求。
如果过期,将再次请求它并提供更新的版本(在处理易失性资源时很有用)。


我很想将此方法从Vue组件移到服务中并在需要的地方导入,而不是在该特定组件的每个实例中都定义它。