首页 > 其他分享 >Vue组件的动态加载和卸载

Vue组件的动态加载和卸载

时间:2024-10-31 17:16:31浏览次数:6  
标签:Vue const image js instance 卸载 组件 id 加载

        组件的动态注册还是比较容易的,使用<component :is="组件id"></component>即可,但动态卸载有难度,相关文献较少。不过,如果巧妙使用vnode,就能轻松实现!

       下图展示了4个代表不同文档材料的Vue组件。为简化起见,每个组件用一个DIV元素表示,其内容为一张图片。只要双击某个图片,即可卸载该图片对应的Vue组件!

组件被删除前 

组件被删除后

1 编写html文件

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>组件的动态注册和卸载</title>
    <style>
        .menu-docs {
            position: absolute;
            width: 450px;
            height: 360px;
            font-size: 16px;
            text-align: center;
            top: 10px;
            padding: 2px;
            border: 1px solid #F00;
            background: rgba(236, 223, 223, 0.2);
            box-shadow: 2px 2px 2px #ccc;
        }
    </style>
    <script type="importmap">
        {
          "imports": {
            "vue": "./js/vue.esm-browser.prod.js"
          }
        }
    </script>
</head>
<body>
<div class="menu-docs" id="app"></div>
<script type="module">
    import {createApp} from 'vue'
    import {AuthorDocs} from "./js/uninstall.js"

    createApp(AuthorDocs).mount('#app')
</script>
</body>
</html>

2 编写js/uninstall.js

        组件的卸载,关键点是需要做两件事情:(1)从页面元素集合中移除当前待删除元素;(2)删除当前Vue实例中的对应组件。

import {defineAsyncComponent, defineComponent, getCurrentInstance, h} from 'vue'

export const AuthorDocs = defineComponent({
    setup() {
        const docs = [ //组件的id及图片内容
            {id: 'computerApp', image: 'image/computerapp.jpg'},
            {id: 'computerGc', image: 'image/computergc.jpg'},
            {id: 'rcp', image: 'image/rcp.jpg'},
            {id: 'spring', image: 'image/spring.png'}
        ]

        const instance = getCurrentInstance()     //应用实例
        const app = instance.appContext.app       //应用相关数据
        docs.forEach(({id, image}, index) =>
            app.component(id, h(asyncComponent, { //h函数渲染
                instance: instance, //当前Vue应用
                id: id,             //材料的id号
                image: image        //材料对应图片URL
            }))
        )
        return {docs}
    },
    template: `
             <div>
               <template v-for="(doc,index) in docs">
                   <component :is="doc.id"></component> <!--动态加载组件-->
               </template>        
             </div>
             `
})

const asyncComponent = defineAsyncComponent( //异步组件
    () => Promise.resolve({
        props: {
            instance: Object,
            id: String,
            image: String
        },
        setup({instance, id, image}) {
            const delDocs = (id) => {
                const vnode = instance.vnode       //获取虚拟元素结点
                const children = vnode.el.children //获得元素集合:div层
                const appComponents = vnode.appContext.components //拿到组件集合
                Object.keys(appComponents)
                    //过滤出computerApp、computerGc、rcp、spring这4个组件
                    .filter(key => appComponents[key].__v_isVNode)
                    .forEach((key, index) => {
                        if (key === id) {             //是当前双击的组件
                            children[index].remove()  //移除当前div层元素
                            //删除当前Vue应用中,组件集合中的对应组件
                            delete appComponents[key]
                        }
                    })
            }
            return {id, image, delDocs}
        },
        template: `
                <div style="float:left;padding:0 20px 10px 2px;">
                  <img :src="image" width="200" height="170"
                     @dblclick="delDocs(id)" title="双击删除">            
                </div>
                `
    })
)

标签:Vue,const,image,js,instance,卸载,组件,id,加载
From: https://blog.csdn.net/acoease/article/details/143406588

相关文章

  • 在使用asm包进行动态类加载的时候的打包问题
     如图所示,开发时使用的jdk包下面的asm包,在进行打包时提示asm包不存在,打包方式使用如下: 目前提供两种解决方案:1:修改打包方式,将jdk的包也打进去:<plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><t......
  • Vue 展示word\excel\pdf 内容
    Vue展示word\excel\pdf内容1、前言项目使用的是若依框架,有一个审核的功能,审核弹窗中需要显示出上传的文件内容,而没有原生的组件可以实现该功能。2、遇到的问题使用iframe组件、不报错,但最后实现的效果是下载而不是展示出来项目是vue2的版本使用@vue-office,直......
  • vue3 类组件装饰器模式配置
    2024年10月31日vue3支持装饰器模式插件借助插件vue-facing-decorator实现类组件装饰器转换npminstall--save-devvue-facing-decorator@rollup/plugin-babel@babel/plugin-proposal-decorators@babel/plugin-proposal-class-propertiesvite.config.ts配置//第一种支......
  • vue2之页面生成PDF导出并适应A4页面
    一、技术vue2 、 elementUI、html2canvas  、jsPDF二、技术官网vue2:https://cn.vuejs.org/elementUi:https://element.eleme.cn/#/zh-CNhtml2canvas:https://html2canvas.hertzen.com/jsPDF:https://www.npmjs.com/package/jspdf三、优缺点优......
  • java+vue计算机毕设冬季供热有限公司网站建设【开题+程序+论文+源码】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着冬季气温的逐渐降低,供热服务成为了城市居民生活中不可或缺的一部分。冬季供热有限公司作为城市供热的主要提供者,承担着保障居民温暖过冬的重要职......
  • java+vue计算机毕设第二课堂学分认定系统【开题+程序+论文+源码】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在高等教育日益重视综合素质培养的今天,第二课堂作为第一课堂的有效补充,其在拓宽学生知识面、提升实践能力、增强综合素质等方面发挥着不可替代的作用......
  • vue3知识点:reactive对比ref
    @目录二、常用CompositionAPI5.reactive对比ref本人其他相关文章链接二、常用CompositionAPI问题:啥叫“组合式API”?答案:请看官方文档:https://v3.cn.vuejs.org/guide/composition-api-introduction.html5.reactive对比ref从定义数据角度对比:ref用来定义:基本类型......
  • vue3第一章基础:创建Vue3.0工程,包括使用vue-cli 创建、使用 vite 创建
    @目录一、vue2、vue3、vue-cli版本、vue-router版本的关联关系1.说明2.不同版本的vue对应的vue-router版本和vuex版本二、创建Vue3.0工程1.使用vue-cli创建2.使用vite创建一、vue2、vue3、vue-cli版本、vue-router版本的关联关系1.说明1.VueCLI4.5以下,对应的是Vue2;Vue......
  • Ant Design Vue 的 a-table 行选择分页时bug处理
    有bug的伪代码如下(示例以id来作为rowKey):<a-table:row-selection="{selectedRowKeys:selectedRowKeys,onChange:onSelectChange}":columns="columns"rowKey="id":pagination="pagination":data-source=&q......
  • Vue组件化-插槽Slot
    认识插槽Slot如何使用插槽slot?插槽的默认内容多个插槽的效果具名插槽的使用◼事实上,我们希望达到的效果是插槽对应的显示,这个时候我们就可以使用具名插槽:具名插槽顾名思义就是给插槽起一个名字,<slot>元素有一个特殊的attribute:name;一个不带name的slot,会带有隐......