Promise的Vue动态组件

时间:2018-09-03 12:22:49

标签: javascript vue.js vuejs2

我遵循了Vue文档,偶然发现了this

const AsyncComponent = () => ({
  // The component to load (should be a Promise)
  component: import('./MyComponent.vue'),
  // A component to use while the async component is loading
  loading: LoadingComponent,
  // A component to use if the load fails
  error: ErrorComponent,
  // Delay before showing the loading component. Default: 200ms.
  delay: 200,
  // The error component will be displayed if a timeout is
  // provided and exceeded. Default: Infinity.
  timeout: 3000
})

我尝试实现这样的组件,当'component'属性是简单组件的new Promise时,它工作得很好,但是我无法使其与import语句一起使用(就像示例中一样。)

问题是,我不知道应该在'MyComponent.vue'中写什么。这是我当前的代码:

MyComponent.vue:

<template>
  <!-- Components with bindings and events -->
</template>

<script>
  // Regular component, works well when imported directly without a promise
  const mainComponent = {
    name: "LoadedCategorySelect",
    data() {
      return {
        categories,
        // ...
      };
    },
    methods: {
      onCatChange(a) { // bound to v-on
        // ..
        this.$emit('newcat', this.somedata);
      },
      onSubCatChange(a) {
        // Same as above
      }
    }
  };

  export default new Promise((resolve, reject) => {
        // Async work
        fetch('http://someurl.com/slug')
          .then((data) => {
            // ...
            resolve(mainComponent);
          })
          .catch((error) => {
            reject(error);
          });
    }
  );
</script>

使用此代码,该组件将呈现,但事件不会被注册。我收到很多错误,例如: Property or method "onSubCatChange" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property

我想念什么?谢谢

PS:我正在使用Vue 2.5

1 个答案:

答案 0 :(得分:1)

问题是您正在从组件中导出Promise,这是完全错误的。

您不必也不必更改有关组件本身的任何内容。它应该像往常一样导出一个组件选项对象,然后您从指南中获取的异步包装程序应该可以正常工作:

// MyComponent.vue
<script>
  export default {
    name: "LoadedCategorySelect",
    data() {
      return {
        categories,
        // ...

const AsyncComponent = () => ({
  // The component to load (should be a Promise)
  component: import('./MyComponent.vue'),
  // A component to use while the async component is loading
  loading: LoadingComponent,
  // A component to use if the load fails
  error: ErrorComponent,
  // Delay before showing the loading component. Default: 200ms.
  delay: 200,
  // The error component will be displayed if a timeout is
  // provided and exceeded. Default: Infinity.
  timeout: 3000
})

这是件好事:不必以任何方式更改组件即可用作高级异步组件。

编辑:回复您的评论:

如果您要将异步数据加载包装到其中,可以-但这并不漂亮,我从未发现需要这样做,但是您可以。重要的是,该函数必须返回一个诺言,该诺言最终会解析为组件对象。

//...
component: () => new Pomise(resolve => {
  const aComponent = import('./MyComponent.vue').then(c => c.default)
  const aData = fetch()....
  Promise.all(aComponent, aDdata).then(([component, data]) => {
    // dosomething with  data
    // then resolve the component: 
    resolve(component)
  })
})