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点击穿透

相关推荐
dy171722 分钟前
element-plus表格默认展开有子的数据
前端·javascript·vue.js
2501_915918414 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员的世界你不懂5 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技5 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip5 小时前
JavaScript二叉树相关概念
前端
一朵梨花压海棠go5 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
attitude.x6 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java6 小时前
CSS3核心技术
前端·css·css3
空山新雨(大队长)6 小时前
HTML第八课:HTML4和HTML5的区别
前端·html·html5