Vue3手写一个全局命令式loading组件

实现效果:

vue文件中,打开全局loading... 2s后关闭

全局命令式loading,效果展示完,直接咱就是上代码 

注册:  
<!-- src/components/myLoading/index.vue -->
<template>
  <!-- 添加name属性,以添加样式
  Transition 主要做一个淡入淡出的 -->
  <Transition name="zhLoading">
    <div v-if="show_toast" class="zh-loading-mark" :style="{ background: bgColor }">
      <div class="zh-loading-body">
        <div class="msg">
          {{ msg }}
        </div>
      </div>
    </div>
  </Transition>
</template>
<script setup>
const props = defineProps({
  show_toast: true,
  msg: "",
  // toast_type: "success",
  duration: 1500
});
const bgColor = 'rgba(43, 41, 39, 0.276)'
</script>
<style scoped lang="scss">
.zh-loading-mark {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;

  .zh-loading-body {
    margin: auto;
    margin-top: 35vh;
    text-align: center;
  }

  /* transition标签样式添加 */
  .zhLoading-enter,
  .zhLoading-leave-to {
    opacity: 0;
  }

  .zhLoading-enter-active,
  .zhLoading-leave-active {
    transition: opacity 0.6s;
  }
}
</style>
// src/components/myLoading/index.js
// 引入vue
import { createVNode, render } from "vue";
// 引入loading组件
import MyLoading from './index.vue';

let mountNode = null;
const showLoading = (options) => {
  const { msg, duration = 2000 } = options;
  //确保只存在一个弹框,如果前一个弹窗还在,就移除
  if (mountNode) {
    document.body.removeChild(mountNode);
    mountNode = null;
  }
  //将options参数传入,并将MyLoading组件转换成虚拟DOM,并赋值给app
  const app = createVNode(MyLoading, {
    msg,
    duration,
    show_toast: true,
  });
  //创建定时器,duration时间后将mountNode移除
  let timer = setTimeout(() => {
    if (mountNode) {
      document.body.removeChild(mountNode);
      mountNode = null;
    }
    clearTimeout(timer);
  }, duration);
  //创建一个空的div
  mountNode = document.createElement('div');
  //render函数的作用就是将Notice组件的虚拟DOM转换成真实DOM并插入到mountNode元素里
  render(app, mountNode);
  //然后把转换成真实DOM的MyLoading组件插入到body里
  document.body.appendChild(mountNode);
}

export default showLoading;
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import showLoading from './components/myLoading/index.js'

const app = createApp(App);

// 绑定全局方法
app.config.globalProperties.$showLoading = showLoading

app.use(router);
app.mount('#app');
使用:
<!-- about.vue -->
<template>
  <el-button @click="onBtn">点击触发</el-button>
</template>
<script setup>
import { getCurrentInstance } from 'vue'

const { proxy } = getCurrentInstance()

function onBtn() {
  proxy.$showLoading({
    msg: '努力加载鸭...',
    show_toast: true
  })
}

</script>

  • 29
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值