文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件

2023-07-05 08:16

关注

本文小编为大家详细介绍“vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

一、基础的动态引入组件:

简单的动态引入的意思是,前端知道要引入哪些组件,将多个组件引入到父组件中,但不渲染它,满足一定条件后,才去在某个位置渲染指定的组件。

<template> <custom-modal ref="custom"></custom-modal></template><script> import {    reactive,    ref,    shallowReactive,    onActivated,    defineAsyncComponent,  } from 'vue'; const customModal = defineAsyncComponent(() => import('./modal/CustomModal.vue')); const custom = ref(); </script>

以上的例子就是通过vue的defineAsyncComponent实现挂载组件,并赋值给customModal ,模板中可以直接使用<custom-modal>作为标签使用,也可以将它赋值给component中的is属性,is属性执向一个变量,可通过业务逻辑动态,更改该变量的值,就可以实现多个组件进行来回的渲染了

<template><component :is="componentKey" ref="custom"></component></template> import {    reactive,    ref,    shallowReactive,    onActivated,    defineAsyncComponent,  } from 'vue'; const componentKey = ref(null); const components: any = shallowReactive({}); const customModal = defineAsyncComponent(() => import('./modal/CustomModal.vue')); componentKey  = customModal

二、复杂的引入:不确定到底引入什么组件,组件的路径由后端返回

将以上代码 添加到项目代码中,并不能实现,虽然引入不报错,但是ref一直为undefined,无法调用动态组件内的open函数。
不断尝试了很多次,得出以下结论

起初是在按钮的click函数内去挂载自定义组件并调用ref函数的,ref为undefined。
尝试多次不能实现功能(这里是挂载与调用最合适的位置),
2.接着又在初始化配置数据时(查询后端sql),axios的then函数内挂载组件,然后点击按钮的地方调用ref内的函数,ref依旧为null。
3. 接着在最外层,调用初始化时挂载,也就是生命周期函数体内,测试还是一样的结果。
4. 接着发现带有async函数体内挂载组件,也无法完成。
5.单独写个函数,不加async,函数内挂载组件,然后再生命周期外调用该函数,按钮内调用ref内的方法,成功弹窗。这并不是我想要的,因为路径不是固定的,它要等到后端sql放回结果,才能执行。

总结:上面的多次测试,得出以下结论,都不能让动态组件ref对象有值
1、不能在组件的事件函数内挂载,

vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件

不能在axios的then函数体内挂载

vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件

不能在带有async声明的函数体内挂载

vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件

不能在vue的生命周期内挂载

vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件

只能在最外层挂载实现,这时ref才是个对象。

好在天无绝人之路;脑海里有个思路:
页面初始化时将项目里所有的全局挂载view组件扔到一个object内,使用component组件,is:对应object内指定的组件对象,然后通过后端的数据,这时后端就不用给组件路径了,给个组件名,我从object中找到挂载的组件然后将对象给is。
const modules = import.meta.glob('@/views/*/**.vue'); // 获取所有项目路径
mudules为views内所有的vue的相对路径,然后循环它,在循环体内实现挂载,将它存入一个对象内,key为相对路径的项目名称(可以截取以下)。

有了上面的思路,通过反复测试和实现,最终功能实现了。

<template><component :is="componentKey" ref="custom"></component></template><script> import {    reactive,    ref,    shallowReactive,    onActivated,    defineAsyncComponent,  } from 'vue';//声明componentkey,用于告诉component当前挂载什么组件,components为一个对象,存放多个不确定的自定义组件。  const componentKey = ref(null);  const components: any = shallowReactive({});  // 组件挂载  const initTableConfig = (gridId, type) => {    queryTableConfig({ gridId }).then(({ data }) => {      if (type === 'main') {        Object.assign(mainConfig, data);        tabsKey.value = -1;      } else {        tabsDetail.value.push(data);        tabsKey.value = tabsDetail.value.length - 1;      }      // 涉及到自定义组件的部分,这里需要提前挂载,在用到时不至于ref为null      XEUtils.objectEach(data.action, (action, key) => {        if (          action.modalCfg &&          action.modalCfg.type === 'CustomModal' &&          action.modalCfg.src        ) {          components[action.actionId] = defineAsyncComponent(            () => import(`../../../${action.modalCfg.src}`)          );          //注意:这里的路径后端只能返回相对路径,不能使用@/xxx/xxx.vue ,不能使用src/xxx/xxx.vue,只能./xxx.vue或者../../xxx/xxx.vue。由于并不确定组件在什么位置,避免容易出错的原则,我在前端通过../../../的形式将路径回退到src下,后端只需要从src下配置路径即可,不用考虑那么多了。如后端src的值为src/xxx/xxx/xxx.vue 则在前端合成的路径就为../../../src/xx/xxx/xxx.vue          componentKey.value = components[action.actionId];          // 为什么componentKey.vue在这里赋值,在后面点击窗口后又赋值,这里能不能省略。//答:这里省略的话,到点击按钮触发时会报错,第一次点击会报错,第二次点击不会报错,窗口正常弹出。可能是因为,组件挂载时并没有引入组件,只在使用时才引入,如果上面不提前将挂载好的组件引入进来,后面触发事件触发时引入在调用ref,执行太快,costom就会报错,所以才会点两次才弹窗。        }      });    });  }; </script>

按钮点击触发事件,确定弹窗要弹出什么组件

} else if (action.modalCfg.type === 'CustomModal') {  // 这里的actionid和组件是对应的,所以在按钮触发后,通过按钮携带的actionid能取到对应的组件。          componentKey.value = components[action.actionId];          custom.value.init(row);        }

经过以上的方式:在任何地方挂载都不会报错,完美解决。
注意:挂载与使用ref不能在同一个方法体内,如果可以的话,页面加载时,执行挂载,需要调用ref时就不会报错。

读到这里,这篇“vue3怎么使用defineAsyncComponent与component标签实现动态渲染组件”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯