javascript - 如果外部加载 JS 文件,Vue 无法注册组件

标签 javascript vue.js vuejs2 vue-component

我在常规 js 文件(不是 .vue)和内联模板中使用 vue。我根据子页面加载的组件很少。我想做的是加载一些全局 vue 变量和 vue 组件,然后动态地使用 jQuery 加载额外的 vue 组件脚本,如果某些容器(例如 #blog)的长度 > 0。

问题是 Vue 抛出一个错误,它找到了 Vue 标签但无法注册组件。

有什么方法可以动态加载 JS 文件吗?我有一个非常大的网站,里面有很多我只想在特定子页面上加载的 js 文件。它适用于所有 jQuery 库,但遗憾的是不适用于 Vue 组件。

下面的示例组件:

Vue.component('blog-entries', {
    name: "blog-entries",
    template: require('js/vue/home/blog/blog.html').template,
    data: function () {
        return {
            blog_entries: [

            ]
        }
    }
});

和错误:

[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

(found in )

加载脚本:

function loadScript(scriptName, callback) {

    if (!_arr[scriptName]) {
        _arr[scriptName] = true;

        var body        = document.getElementsByTagName('body')[0];
        var script      = document.createElement('script');
        script.type     = 'text/javascript';
        script.src      = scriptName;

        // then bind the event to the callback function
        // there are several events for cross browser compatibility
        // script.onreadystatechange = callback;
        script.onload = callback;

        // fire the loading
        body.appendChild(script);

    } else if (callback) {

        callback();

    }

};

最佳答案

var vapp = new Vue({
  el: '#app',
  data: function() {
    return {
      componentName: ''
    }
  },
  computed: {
    currentComponent: function() {
      var vm = this;
      if (!vm.componentName) return;

      if (!vm.$options.components[vm.componentName] //if not registered locally
          && !Vue.options.components[vm.componentName]) {//nor globally yet

        //load the component async'ly
        Vue.component(vm.componentName, function(resolve) {
          //adjust the path to where your component files are
          var filePath = 'https://elfan.net/vue-components/' + vm.componentName + '.vue.js';
          loadScript(filePath, resolve);
        });
      }
      return vm.componentName;
    }
  }
});

/*below is your own third party script loader*/
var _arr = {};
function loadScript(scriptName, callback) {

    if (!_arr[scriptName]) {
        _arr[scriptName] = true;

        var body        = document.getElementsByTagName('body')[0];
        var script      = document.createElement('script');
        script.type     = 'text/javascript';
        script.src      = scriptName;

        // then bind the event to the callback function
        // there are several events for cross browser compatibility
        // script.onreadystatechange = callback;
        script.onload = callback;

        // fire the loading
        body.appendChild(script);

    } else if (callback) {

        callback();

    }

}
<!DOCTYPE html>
<html>
  <body>

    <div id="app">
      <input v-model="componentName">
      <div :is="currentComponent"></div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
    <script src="app.js"></script>

  </body>

</html>

在主应用程序(加载子页面的应用程序)中,尝试如下操作:

Vue.component('blog-entries', function(resolve) {
    loadScript('blog-entries.js', resolve);
})

其中“blog-entries”应与您的 Vue 组件名称相同,“blog-entries.js”是包含您要动态加载的 Vue 组件的 js 文件。

编辑:跟进,这里我把动态加载vue组件的完整代码放在这里。该组件将在用户键入时立即加载和呈现。 您可以尝试输入“ant”、“bird”或“cat”。我在我的服务器上放置了具有这些名称的 vue 组件。

关于javascript - 如果外部加载 JS 文件,Vue 无法注册组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45847237/

相关文章:

javascript - 从同一域中的不同选项卡/窗口访问弹出窗口

javascript - 捕捉 "Display forbidden by X-Frame-Options”

javascript - 使多个 Vuejs javascript 文件协同工作的最佳实践

javascript - 无法在 nuxt 中使用 axios 插件

vue.js - vue-router 既不监视路由也不监视导航守卫开火

javascript - 车轮事件,以及 "mousewheel"的 deltaY 值

javascript - Canvas 中的图像预加载

javascript - Vuejs 类型错误 : Cannot read property 'placeholder' of undefined"

javascript - 如何使用 Vue 构建 UI 框架

vue.js - 使用 Vue-CLI 创建的应用程序提供 404 页面