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

相关推荐
糕冷小美n8 小时前
elementuivue2表格不覆盖整个表格添加固定属性
前端·javascript·elementui
小哥不太逍遥8 小时前
Technical Report 2024
java·服务器·前端
沐墨染8 小时前
黑词分析与可疑对话挖掘组件的设计与实现
前端·elementui·数据挖掘·数据分析·vue·visual studio code
anOnion8 小时前
构建无障碍组件之Disclosure Pattern
前端·html·交互设计
threerocks8 小时前
前端将死,Agent 永生
前端·人工智能·ai编程
问道飞鱼9 小时前
【前端知识】Vite用法从入门到实战
前端·vite·项目构建
爱上妖精的尾巴9 小时前
8-10 WPS JSA 正则表达式:贪婪匹配
服务器·前端·javascript·正则表达式·wps·jsa
Zhencode9 小时前
Vue3响应式原理之ref篇
vue.js
shadow fish10 小时前
react学习记录(三)
javascript·学习·react.js
小疙瘩10 小时前
element-ui 中 el-upload 多文件一次性上传的实现
javascript·vue.js·ui