vue.js загружает скрипт из cdn, а затем компонент vue (без веб-пакета) - PullRequest
1 голос
/ 20 апреля 2019

Как я могу загрузить пользовательский скрипт из 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 Ответ

1 голос
/ 20 апреля 2019

Это должно сделать это:

    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 в службу и импортировать его при необходимости, а не определять его в каждом экземпляре этого конкретногокомпонент.

...