首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Vue 3中以编程方式创建组件实例?

如何在Vue 3中以编程方式创建组件实例?
EN

Stack Overflow用户
提问于 2021-10-27 03:29:12
回答 2查看 1K关注 0票数 0

我有一个用于常见场景的Vue 2模式:以编程方式创建一个实例,以便在模板外部的动态内容上打开Modal/Dialog/Lightbox。

在Vue 2中,我发现了这样的模式:

代码语言:javascript
运行
复制
// DialogService.js

export default {
  alert(text) {
    const DialogClass = Vue.extend(DialogComponentDef);
    let dialog = new DialogClass({ propsData: { text } });

    dialog.$on('close', () => {
      dialog.$destroy();
      dialog.$el.remove();
      dialog = null;
    });

    // mount the dynamic dialog component in the page
    const mountEl = document.createElement('div');
    document.body.appendChild(mountEl);
    dialog.$mount(mountEl);
  },
};

知道Vue.extends$on$destroy已经不存在了,我怎么才能在Vue 3中实现这一点呢?您可以查看clicking here提供的DialogService.js的完整示例。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-29 18:03:49

以下是如何在Vue 3中处理createApp,但上下文(存储、插件、指令...)将不会被保留。

代码语言:javascript
运行
复制
// DialogService.js
import { createApp } from 'vue';

export default {
  alert(text) {
    const mountEl = document.createElement('div');
    document.body.appendChild(mountEl);

    const dialog = createApp({ extends: DialogComponentDef }, {
      // props
      text,
      // events are passed as props here with on[EventName]
      onClose() {
        mountEl.parentNode.remvoeChild(mountEl);
        dialog.unmount();
        dialog = null;
      },
    });

    dialog.mount(mountEl);
  },
};

为了保持上下文,在hrender Vue方法中可以看到更复杂的东西:https://github.com/vuejs/vue-next/issues/2097#issuecomment-709860132

票数 0
EN

Stack Overflow用户

发布于 2021-10-27 06:57:13

Vue 3没有提供通用的事件总线。它可以被像mitteventemitter3这样的轻量级第三方替代方案所取代。

组件可以使用teleport安装在应用程序元素层次结构之外。这之前已经在Vue 2和第三方portal-vue库中可用。模态和其他屏幕UI元素是它的常见用例

代码语言:javascript
运行
复制
<teleport to="body">
  <DialogComponent ref="dialog" @close="console.log('just a notification')">
   Some markup that cannot be easily passed as dialog.value.show('text')
  </DialogComponent>
</teleport>

其中DialogComponent控制自己的可见性,不需要像原始代码片段那样显式卸载。父级卸载时会自动执行清理:

代码语言:javascript
运行
复制
<teleport to="body">
  <div v-if="dialogState">
    <slot>{{dialogText}}</slot>
  </div>
</teleport>

代码语言:javascript
运行
复制
let dialogState = ref(false);
let dialogText = ref('');
let show = (text) => {
  dialogText.value = text;
  dialogState.value = true;
} ;
...
return { show };

对于更复杂的场景,需要管理多个实例,或者需要在业务逻辑的组件外部访问show,则需要在组件层次结构的顶层挂载一个远程端口。在这种情况下,可以通过应用程序传递的事件总线实例可用于交互。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69732406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档