Как я могу динамически загружать вложенный компонент в Vuejs без жесткого кодирования URL-адреса

Я следил за Маркусом Оберленером для загрузки компонентов Vue через http. У нас есть компонент Vue, предварительно скомпилированный в виде файла .js, размещенного на отдельном сервере. Когда пользователь переходит к этому компоненту загрузчика ниже, вызов externalComponent () успешно выбирает файл .js и отображает компонент на этой странице. Это отлично. Это работает, только если мы жестко закодируем URL-адрес в компоненте загрузчика.

Мы встраиваем в наш сайт архитектуру плагинов. Мы написали несколько одностраничных файлов компонентов Vue. Каждый из этих файлов представляет собой плагин. Мы предварительно скомпилировали эти файлы .vue в файлы .js в соответствии с полезным руководством Маркуса Оберленера здесь: https://github.com/maoberlehner/distributed-vue-applications-loading-components-via-http.

У нас также есть компонент Vue на нашем основном сайте - назовем его компонентом загрузчика - который извлекает файл .js и отображает его в компонент с помощью метода externalComponent (), продемонстрированного в учебнике Маркуса. Это работает, но поскольку MyComponent является константой, определенной вне объекта данных компонента загрузчика, мы не можем динамически вставлять plugin_id из маршрутизатора vue в URL-адрес файла .js.

Если вам интересно, почему наши URL-адреса не заканчиваются на .js, это потому, что вместо этого мы передаем URL-адрес конечной точке на нашем сервере. Эта конечная точка получает файл .js и возвращает его нашему клиенту.

<template>
  <div>
    <MyComponent />
  </div>
</template>

<script>
import util from "~/js/util.js";

let MyComponent = () =>

  /* If we hadcode the url, the page renders no problemo.
   *
   * util.externalComponent("http://localhost:8081/api/plugins/167/code");
   */
  
  /* However, we'd like to fetch the plugin_id from the Vue router and inject that into the argument 
   * as I've tried to achieve in the line of code below. 
   *
   * The following code does not work because Vue apparently loads the MyComponent element in the DOM
   * before executing the created() hook. We get the error "plugin_id is not defined."
   */
    util.externalComponent(
      "http://localhost:8081/api/plugins/" + plugin_id + "/code"
    );


export default {
  name: "plugin",
  components: {
    MyComponent
  },
  data() {
    return {
      plugin_id: null
    };
  },
  created() {

   /* This line does indeed populate the plugin_id data variable, although this happens after the 
    * page attempts to load MyComponent
    */
    this.plugin_id = this.$route.params.plugin_id;
  }
};
</script>

Итак, как мы можем изменить этот код, чтобы динамически вставлять plugin_id в URL-адрес?

Между прочим, это проект nuxt.


Обновлять

Вот подход, который работает при первой загрузке страницы, но последовательные загрузки все еще остаются проблемой. В частности, первый компонент просто загружается снова, независимо от того, каким может быть новый идентификатор плагина. Но это похоже на правильное направление ...

<template>
  <div>
    <component v-bind:is="component" v-if="loadedUrl"></component>
    {{ plugin_id }}
  </div>
</template>

<script>
import util from "~/js/util.js";

export default {
  name: "plugin",
  props: [],
  data() {
    return {
      loadedUrl: false,
      component: null
    };
  },

  beforeRouteEnter(to, from, next) {
    next(vm => {
      vm.loadedUrl = false;
      vm.component = () =>
        util.externalComponent(
          "http://localhost:8081/api/plugins/" + to.params.plugin_id + "/code"
        );
      vm.loadedUrl = true;
      next();
    });
  },
  beforeDestroy() {
    //does not seem to help.
    console.log("in beforeDestroy");
    this.component = null;
  }
};
</script>

person GNG    schedule 29.10.2020    source источник
comment
используйте props vuejs.org/v2/guide/components-props.html.   -  person Jazuly    schedule 29.10.2020
comment
Но как эта строка кода, которая находится выше экспорта по умолчанию {...}, может знать, что это за свойства? Приведите пример.   -  person GNG    schedule 29.10.2020
comment
Я обновляю свой вопрос, используя подход, который работает при первой загрузке страницы, но последовательные загрузки все еще остаются проблемой. В частности, первый компонент просто загружается снова, независимо от того, каким может быть новый идентификатор плагина.   -  person GNG    schedule 30.10.2020
comment
Я бы попробовал вместо этого использовать watch(). Что-то вроде watch: { '$route.params.plugin_id': { handler() { this.component = () => /* ... */ }, deep: true, immediate: true } }   -  person moriartie    schedule 31.10.2020