Vue Динамический Компонент от Promise - PullRequest
0 голосов
/ 03 сентября 2018

Я следовал документации Vue и наткнулся на это :

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 голосов
/ 03 сентября 2018

Проблема в том, что вы экспортируете 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)
  })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...