Vue 3 расширяет компоненты vue.js из сторонней библиотеки в defineComponent.

Я хочу использовать элемент-плюс сторонней библиотеки в своем компоненте. В setup defineComponent подразумевается этот компонент. В консоли будет предупреждение Failed to resolve component: el-radio at <App>

В о маршрутизаторе Вот about.vue

<template>
  <div id="popup-content"></div>
</template>

<script>
import {
  onMounted, createApp, defineComponent, nextTick,
} from 'vue';
import Test from '@/components/Test.vue';

export default {
  setup() {
    onMounted(() => {
      const myNewComponent = defineComponent({
        extends: Test,
      });
      createApp(myNewComponent).mount('#popup-content');
      nextTick(() => {
        createApp(myNewComponent).mount('#popup-content');
      });
    });
  },
}

В тестовом компоненте используется компонент element-plus el-raido, Test.vue

<template>
  <el-radio v-model="radio" label="1">备选项</el-radio>
  <el-radio v-model="radio" label="2">备选项</el-radio>
</template>

<script>
export default {
  data() {
    return {
      radio: '1',
    };
  },
};
</script>

Я добавил element-plus и зарегистрировал все в main.js

import { createApp } from 'vue';
import ElementPlus from 'element-plus';
import 'element-plus/lib/theme-chalk/index.css';
import App from './App.vue';

const app = createApp(App);


app.use(ElementPlus);
app.mount('#app');

введите здесь описание изображения

Я нашел этот вопрос Расширить компонент vue.js из сторонней библиотеки< /а>


person Anderson Min    schedule 20.03.2021    source источник


Ответы (2)


Я действительно-правда не понимаю, чего вы пытаетесь достичь, расширяя свой прекрасный Test компонент, НО...

Vue 3 сильно отличается от Vue 2 — многие глобальные API (например, регистрация компонентов) являются больше не глобальный, но привязан к экземпляру приложения (созданный createApp)

Таким образом, даже если вы зарегистрируете компоненты Element в main.js (app.use(ElementPlus);), другой экземпляр приложения (почему!?), созданный в onMounted хуке компонента about.vue, ничего не знает о компонентах! Вот и причина ошибки...

Вы должны зарегистрировать компоненты в каждом экземпляре приложения, созданном createApp, в котором вы хотите использовать их....

person Michal Levý    schedule 20.03.2021
comment
Оно работает. Я нашел этот блог, ссылка. Я хочу добавить компонент vue во всплывающее окно mapbox-gl. В блоге не показан способ добавления компонента сторонней библиотеки во всплывающий файл. Итак, я пришел сюда. - person Anderson Min; 21.03.2021
comment
Хорошо, это многое объясняет. Но расширение не требуется, если вы никаким образом не изменяете исходный компонент. И создание нового приложения Vue (и регистрация всех компонентов Element) каждый раз, когда вы хотите показать всплывающее окно, кажется довольно неэффективным. Вы можете сделать что-то подобное, если используете слоты. Взгляните на vue-mapbox, и это всплывающий компонент, если вы хотите узнать больше... - person Michal Levý; 21.03.2021
comment
Я знаю, как использовать слоты, также см. размещенную вами ссылку popop component и см. слот рендеринга. но не знаю, как сделать что-то подобное использовать слоты. У меня есть много разных всплывающих окон, это было бы огромным улучшением. У вас есть время вести блог? - person Anderson Min; 22.03.2021
comment
Кроме того, в моем шаблоне всплывающего окна много контента. Лучше использовать функции рендеринга, чем расширяющий компонент? поскольку vue-mapbox использует функции рендеринга. - person Anderson Min; 22.03.2021

Как ответил @Michal Levý, мне нужно зарегистрировать компоненты в каждом экземпляре приложения, созданном createApp.

Вот рабочая версия about.vue, если кому понадобится.

<template>
  <div id="popup-content"></div>
</template>

<script>
import {
  onMounted, createApp, defineComponent, nextTick,
} from 'vue';
import Test from '@/components/Test.vue';
import ElementPlus from 'element-plus';
import 'element-plus/lib/theme-chalk/index.css';

export default {
  setup() {
    onMounted(() => {
      const myNewComponent = defineComponent({
        extends: Test,
      });
      const app1 = createApp(myNewComponent);

      nextTick(() => {
        app1.use(ElementPlus);
        app1.mount('#popup-content');
      });
    });
  },
}
person Anderson Min    schedule 21.03.2021