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

Posted

技术标签:

【中文标题】vue.js 从 cdn 加载脚本,然后组件 vue(没有 webpack)【英文标题】:vue.js load script from cdn and then component vue (without webpack) 【发布时间】:2019-09-10 13:42:06 【问题描述】:

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

Vue.component('example', 

   // LOAD ANOTHER SCIPT : SAY cdn.myScript

    // render function as alternative to 'template'
    render: function (createElement) 
        return createElement(
            // String | Object | Function
            // An html tag name, component options, or function
            // returning one of these. Required.
            'h2',
            // Object
            // A data object corresponding to the attributes
            // you would use in a template. Optional.
            
                style: 
                    color: 'red', 
                ,
                domProps: 
                    innerHTML: 'My Example Header'
                
            ,

    ),
    methods:
      a:function(z)
         myScript.hello();
      
     
);

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

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

【问题讨论】:

【参考方案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();

这可以防止多次附加相同的&lt;script&gt;。 在许多情况下,资源不会过期(或过期无关紧要),如果脚本重新加载已被附加,您可能希望跳过它。即:if(!existing) /* append the script */ .

通过删除先前附加的&lt;script&gt; 并再次添加它,我们将过期评估传递给浏览器,然后传递给提供资源的服务器。

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


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

【讨论】:

以上是关于vue.js 从 cdn 加载脚本,然后组件 vue(没有 webpack)的主要内容,如果未能解决你的问题,请参考以下文章

不能使用 Vue JS 作为 CDN 的 3rd 方组件

从 CDN 库动态加载 vue 组件

我定义了一个Vue实例,但我找不到它

Vue - 添加没有 webpack 的 CDN 组件

vue.js基础

从不同的子域加载 Vue.js 异步组件