Как вы монтируете сборку VueJS UMD на существующий HTML?

Я пытался взять пару небольших компонентов из нашего основного приложения для использования на целевой странице, но безуспешно!

У меня есть существующий HTML в DOM, скажем:

<div id="app">
 <h1>Demo Feature #1</h1>
 <demo-component />
</div>

У меня есть следующий файл записи, marketing.ts:

import Vue from "vue";
import Demo from "Demo.vue";

new Vue({
 el: 'app',
  components: {
    'demo-component': Demo,
  }
});

Когда выходная сборка запускается на сайте, DOM в конечном итоге выглядит следующим образом:

<!--function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }-->

Я ожидал, что пользовательский тег HTML будет заменен моим компонентом Vue.

В документах говорится, что это должно быть так:

Если ни функция рендеринга, ни опция шаблона отсутствуют, встроенный в DOM HTML-код монтируемого элемента DOM будет извлечен как шаблон. В этом случае следует использовать сборку Vue Runtime + Compiler.

Кроме того, документы переходят в состояние :

При использовании vue-loader или vueify шаблоны внутри файлов * .vue предварительно компилируются в JavaScript во время сборки. В конечном комплекте компилятор не нужен, поэтому вы можете использовать сборку только во время выполнения.

В этом случае я использую VueCLI (с Vue Loader) для создания вывода, который, как я понимаю, является сборкой только во время выполнения.

Компонент отлично работает в полноценном приложении. Что бросается в глаза, так это отсутствие render. Когда я использую это, он заменяет DOM всем поставляемым компонентом и теряет то, что уже было внутри.

Можно ли извлечь несколько компонентов с помощью сборки библиотеки и отобразить их в существующей модели DOM?


Дальнейшие подробности:

  • Используя команду сборки vue-cli-service build --target lib --inline-vue --dest dist/lib/marketing --name marketing src/marketing.ts --no-clean
  • Использование VueCLI 4.2.2
  • Использование компонентов TypeScript и Vue Class
  • Это CodePen показывает, что можно сделать

person Ste Pammenter    schedule 06.03.2020    source источник


Ответы (2)


Я сделал это с помощью ...

1) упаковка моего компонента в файл js

import MyWidgit from './MyWidgit.vue';

// eslint-disable-next-line import/prefer-default-export
export const mount = (el, props) =>
  new window.Vue({
    el,
    render: h => h(Filter, {props})
  });

2) использование свертки для генерации кода (я думаю, что он лучше подходит для генерации библиотек)

{
    input: `./src/${widgetName}/${widgetName}.js`, // Path relative to package.json
    output: {
      format: 'umd',
      name: widgetName,
      file: `./dist/${widgetName}.js`,
      exports: 'named',
      external: ['vue'], // requires vuejs lib to be loaded separately
      globals: {
        vue: 'Vue',
      },
    },
    //... etc
}

3) добавить в html

<script src="/dist/vue.js"></script>
<script src="/dist/mywidgit.js"></script>

<!-- mywidgit mount target-->
<div id="widget1"></div>

<!-- init and mount -->
<script>
  mywidgit.mount('#widget1', {
    msg: 'all is well',
  });
</script>
person Daniel    schedule 06.03.2020
comment
Спасибо за этот ответ. К сожалению, этот подход не будет хорошо масштабироваться для наших нужд, поскольку у нас будет несколько компонентов - идентификаторы для каждого из них станут громоздкими. - person Ste Pammenter; 10.03.2020
comment
Этот подход использовался в проекте, где есть несколько (10+) виджетов, которые объединяются одновременно. Конфигурация объединения создается функцией, в которую я передаю ей widgetName. В моем случае я передал имена вручную (так как это позволяет легко пропускать файлы), но у вас может быть сценарий, который также выполняет итерацию по папке. Я бы сказал, что он очень хорошо масштабируется, и я думаю, что rollup - предпочтительный способ (по сравнению с webpack) для публикации такого набора компонентов. - person Daniel; 10.03.2020
comment
Как это обрабатывается: mywidgit.mount('#widget1', { msg: 'all is well', }); в вашем HTML? Вы используете Rollup со своим HTML? Это то, в чем я не был уверен, т.е. нужно ли вам писать это для каждого идентификатора, используемого на странице? Извините, я не знаком с инструментом, так что это может быть проблемой. - person Ste Pammenter; 11.03.2020
comment
Хорошо, я вижу. Мне нужно делать это индивидуально. Настройка предназначена для библиотеки виджетов, где один или два (из многих) будут использоваться на странице. Но похоже, что вы не собираетесь его использовать. Я считаю, что неправильно понял ваше предполагаемое использование - person Daniel; 11.03.2020
comment
Ах да, извините, что было непонятно. Мы используем его в более традиционном смысле, когда некоторые части нашего приложения переносятся на наш маркетинговый сайт через CMS. - person Ste Pammenter; 11.03.2020

Чтобы решить эту проблему, я удалил аргумент --inline-vue из сборки CLI и добавил Vue.JS через CDN, т.е.

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>

Я считаю, что это должно работать с одной библиотекой, поэтому потенциально это проблема инструмента сборки.

person Ste Pammenter    schedule 10.03.2020
comment
Я оставлю это как ответ, чтобы помочь кому-либо еще, но я не верю, что это правильный подход. - person Ste Pammenter; 10.03.2020