vue3动态组件应该如何实现

问题遇到的现象和发生背景

vue2 升级 vue3 后 动态组件 不可用

遇到的现象和发生背景,请写出第一个错误信息

img


一个工作流平台,有一个界面查询全部的待办流程,每一个流程都是一个组件,组件的地址存到了数据库中,点击标题跳转到不同的组件,vue2 使用如下代码能实现,升级到vue3 后代码失效,尝试过 defineAsyncComponent 报 Failed to resolve module specifier,请问在vue3中这种应该如何实现

<template>
  <div>
    <el-dialog :title="title" :visible.sync="open" append-to-body>
      <component :timer="timer" v-if="dynamicComponent" :is="dynamicComponent" :formId.sync="formId" :actId="actId"></component>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    name: 'dynamicDialog',
    props: {
      todo: {
        type: Object,
        default: null
      },
    },
    computed: {
      dynamicComponent() {
        if (this.todo != null) {
          this.timer = new Date().getTime();
          this.formId = this.todo.id;
          this.actId = this.todo.actId;
          let filename = this.todo.formView;
          this.title = this.todo.todoTitle;
          this.open = true;
          return (resolve) => require([`@/views/${filename}.vue`], resolve);
        } else {
          return null;
        }
      },
    },
    created() {

    },
    data() {
      return {
        formId: "",
        timer: "",
        open: false,
        title: ""
      }
    },
    methods: {}
  }
</script>

在 vue3 中,动态组件的用法有所改变。

首先,你可以使用 defineAsyncComponent 来定义异步组件,但是你需要使用 import 进行模块的加载,而不能使用 require。

其次,动态组件的写法也有所改变。在 vue3 中,你可以使用如下的写法:

<template>
  <component :is="dynamicComponent" />
</template>
<script>
  import { defineAsyncComponent } from 'vue';

  export default {
    setup() {
      const dynamicComponent = ref(null);

      return {
        dynamicComponent
      };
    }
  }
</script>

你可以将动态组件的地址存储在一个 ref 中,然后通过 :is 绑定到组件上。

你可以参考如下的代码来更新你的程序:

<template>
  <div>
    <el-dialog :title="title" :visible.sync="open" append-to-body>
      <component v-if="dynamicComponent" :is="dynamicComponent" :timer="timer" :formId.sync="formId" :actId="actId"></component>
    </el-dialog>
  </div>
</template>
<script>
  import { defineAsyncComponent } from 'vue';
  import { ref } from 'vue';

  export default {
    name: 'dynamicDialog',
    props: {
      todo: {
        type: Object,
        default: null
      },
    },
    setup() {
      const timer = ref('');
      const formId = ref('');
      const actId = ref('');
      const title = ref('');
      const open = ref(false);
      const dynamicComponent = ref(null);

      return {
        timer,
        formId,
        actId,
        title,
        open,
        dynamicComponent,