vue2 & [vue3 ts]全局loading挂载

vue2

1.新建loading.vue 界面

html 复制代码
<template>
  <div class="loading"
       id="loadingPage"
       v-show="show"
       style="pointer-events: none"
  >
    <Spin
        :tip="tipMsg"
        size="large"
        class="spin"
    ></Spin>
  </div>
</template>
<script>
import {defineComponent, ref,} from 'vue'
import {Spin} from 'ant-design-vue'
import {getEl} from "@/util/utils"
import logger from "@/util/logger"

export default defineComponent({
  name: "loading",
  props: {
    show: Boolean
  },
  components: {Spin},
  setup() {
    let show = ref(false)
    let tipMsg = ref(null)
    const showLoad = (msg) => {
      show.value = true
      if (msg) {
        tipMsg.value = msg
      } else {
        tipMsg.value = ''
      }
      // 一级菜单
      let elMain = getEl("container")
      if (elMain) {
        elMain.style.pointerEvents = 'none'
      }
    }

    const hideLoad = () => {
      show.value = false
      setTimeout(() => {
        // 一级菜单
        let elMain = getEl("container")
        if (elMain) {
          elMain.style.pointerEvents = 'auto'
        }
      }, 400)
    }

    return {
      show,
      showLoad,
      hideLoad,
      tipMsg,
    }
  },
})
</script>

<style scoped lang="scss">
#loadingPage {
  background-color: rgba(36, 34, 34, 0.5);
  text-align: center;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  pointer-events: none;
}

.loading {
  pointer-events: none;
}

.spin {
  position: relative;
  top: 50%;
  pointer-events: none !important;
}

</style>

2.创建loading.js

javascript 复制代码
import {createApp} from "vue"
import Loading from '@/components/loading'

export default {
    loading: null,
    install(app, options) {
        if (this.loading) {
            // 防止多次载入
            app.config.globalProperties.$loading = this.loading
            return
        }
        //app.use() 对同一个插件多次调用,该插件只会被安装一次
        let dom = document.body.appendChild(document.createElement("div"))
        this.loading = createApp(Loading,{...options}).mount(dom)
        app.config.globalProperties.$loading = this.loading;
    }
}

3.在main.js中挂载,导入创建的函数,先使用后挂载

javascript 复制代码
import loadConfig from "./util/loading"
app.use(loadConfig)
.mount("#app")

4.界面中使用

javascript 复制代码
const {proxy} = getCurrentInstance()

const getData = ()=>{
  proxy.$loading.showLoad(t("uploading"))
setTimeout(()=>{
 proxy.$loading.hideLoad()
},5000)
}

vue3 + ts 中挂载全局Loading时使用Vue2的方法时会有很多问题 ,应该是不支持这样去做了。使用组件会一劳永逸

问题1:在ts中使用需要声明类型

新建一个 类型文件.d.ts

javascript 复制代码
type Load = {
    showLoad: (msg?: string) => void,
    hideLoad: () => void
}

declare module "@vue/runtime-core" {
    interface ComponentCustomProperties {
        $hideLoad:Function;
        $showLoad:Function;
        $loading: Load
            // Record<string, any> | null | undefined;
    }
}

export {}

如果不添加这个导出 export{} 在其他界面因为追加了类型声明导致在.vue中的界面所有从'vue'中引入的方法都找不到报错"module vue has no exported member ref",添加后就好了

问题2:即时导出Loading组件里的方法在外部界面中使用也无法找到; 使用各种姿势我也是找不到啊

javascript 复制代码
install(app: App) {
        const Vnode: VNode = createVNode(GlobalLoading)
        render(Vnode, document.body)
        app.config.globalProperties.$loading = {
            hideLoad: Vnode.component?.exposed?.hideLoad(),
            showLoad: Vnode.component?.exposed?.showLoad(),
        },
        app.config.globalProperties.$hideLoad =  Vnode.component?.exposed?.hideLoad(),
        app.config.globalProperties.$showLoad =  Vnode.component?.exposed?.showLoad()
    }

问题3:

在界面中使用 是这样才不报错,但是找不着啊,不知道为什么

javascript 复制代码
const {proxy} = getCurrentInstance() as ComponentInternalInstance
 proxy?.$loading.hideLoad()  //  找不到实现不了调用不了 

最终通过创建组件引入来调用

loading.vue那个文件还是那个文件

1.创建挂载组件文件,这段参考别人的,地址是找不着了

javascript 复制代码
import {createApp} from "vue";
import Loading1 from "@/library/antds/loading/LoadingCustom.vue";

let loadingInstance;

const LoadingGlobal = {
    showLoad(message?:string) {
        if (!loadingInstance) {
            const loadingApp = createApp(Loading1);
            const mountNode = document.createElement("div");
            document.body.appendChild(mountNode);
            loadingInstance = loadingApp.mount(mountNode);
        }
        loadingInstance.showLoad(message);
    },
    hideLoad() {
        if (loadingInstance) {
            loadingInstance.hideLoad();
        }
    }
};

export default LoadingGlobal;

2.界面中使用

javascript 复制代码
import LoadingGlobal from "@/plugins/loading";

LoadingGlobal.showLoad("收货入库中,请稍等~")

同时需要注意modal点击穿透

相关推荐
@阿猫阿狗~几秒前
金三银四:20道前端手写面试题
前端·面试·职场和发展
汪子熙2 分钟前
什么是 Angular 开发中的 Dumb components
前端·javascript·angular.js
lzhdim3 分钟前
Ini文件读写配置工具类 - C#小函数类推荐
开发语言·前端·python·c#
等你许久_孟然7 分钟前
【CSS/HTML】实现可扩展性的页面布局
前端·css·html
前端李易安9 分钟前
javaScript中如何实现函数缓存,案例解析
开发语言·javascript·缓存
Ian102517 分钟前
webGL入门(五)绘制多边形
开发语言·前端·javascript·webgl
终末圆17 分钟前
TypeScript 基本使用指南【前端 26】
前端·javascript·typescript
susu108301891120 分钟前
前端vue3中父div width: 40%; height: 62%; 子div如何设置相对父位置不变
开发语言·前端·javascript
It'sMyGo20 分钟前
js中的深拷贝与浅拷贝 手写深拷贝代码
开发语言·前端·javascript
WHabcwu23 分钟前
Spring Web MVC课后作业
java·前端·后端·spring·html·mvc