总结vue2和vue3挂载自定义组件

文章展示了如何在Vue2和Vue3中创建并使用一个自定义的loading组件。在Vue2中,通过新建loading.vue文件并编写样式和逻辑,然后在index.js中创建实例并挂载到DOM。Vue3版本则利用Vue的新特性如setup脚本、createApp和动态挂载进行实现。在需要的地方引入并调用,延迟关闭组件的示例也一同给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、vue2

1. 新建一个loading.vue文件并书写逻辑样式

<template>
  <div class="loading-box">
    <div class="flex items-center" style="color: #165dff">
      <span>{{ title }}</span>
    </div>
  </div>
</template>

<script>
export default {
}
</script>

<style lang="scss" scoped>
.loading-box {
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(255, 255, 255, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10000;
  .icon {
    animation: loading 1s steps(12, end) infinite;
  }
}

@keyframes loading {
  0% {
    transform: rotate3d(0, 0, 1, 0deg);
  }
  100% {
    transform: rotate3d(0, 0, 1, 360deg);
  }
}
</style>

2. 在同级目录新建index.js文件

import Vue from "vue";
import loading from "./loading.vue";

export default function DLoading (options) {
  const loadingConstructor = Vue.extend(loading) // 返回一个“扩展实例构造器”。
  const instance = new loadingConstructor({ // 实例化vue实例
    el: document.createElement('div'), // 将实例挂载在创建的div上
    data: options // 将传入组件的值,赋值给实例的data
  })
  document.body.appendChild(instance.$el) // 把创建的div添加到body中
  DLoading['close'] = function () {
    instance.$destroy() // 销毁实例
    document.body.removeChild(instance.$el) // 删除创建的div
  }
  return instance
}

 3. 在需要使用的地方引入

import DLoading from './components/DLoading';

...

mounted() {
  DLoading({ title: '获取中。。。' })
  setTimeout(() => {
    DLoading.close()
  }, 2000);
},

二、vue3

1. 新建一个loading.vue文件并书写组件逻辑样式

<template>
  <div class="loading-box">
    <div class="flex items-center" style="color: #165dff">
      <IconPark type="redo" class="icon"></IconPark>
      <span>{{ title }}</span>
    </div>
  </div>
</template>

<script setup>
import { nextTick, onMounted, reactive, ref, watch, onUnmounted } from "vue";
import { IconPark } from '@icon-park/vue-next/es/all';

const props = defineProps({
  title: {
    type: String,
    default: '加载中...',
  },
});
</script>

<style lang="less" scoped>
.loading-box {
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(255, 255, 255, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10000;
  .icon {
    animation: loading 1s steps(12, end) infinite;
  }
}

@keyframes loading {
  0% {
    transform: rotate3d(0, 0, 1, 0deg);
  }
  100% {
    transform: rotate3d(0, 0, 1, 360deg);
  }
}
</style>

2. 在同级目录下新建index.js

import { createApp } from "vue";
import loading from "./loading.vue";

export default function DLoading (options) {
  const mountNode = document.createElement('div')
  document.body.appendChild(mountNode)
  const app = createApp(loading, {
    ...options
  })
  // 调用close方法销毁组件
  DLoading['close'] = function () {
    app.unmount()
    document.body.removeChild(mountNode)
  }
  return app.mount(mountNode)
}

3. 在需要使用的地方引入

import DLoading from "@/components/DLoading/index";


DLoading({title: '上传中'})
setTimeout(() => {
  DLoading.close()
}, 2000);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

inticaler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值