今天翻遍全网也没有找到Vue3中一个类似Vue2中挂载在原型链上的$massage这样的文章, 然后我突然想到Ant Design of Vue组件库支持vue3.0, 这样就开始了漫长且痛苦的翻源码之路

github中找到了如下几个文件


从头来说我希望的是一个调用方式为this.$loading()的loading组件
我第一想到的是一个类似message的写法
使用vue2的方式没有成功运行起来, 我想到了去找组件库, 也就是antd of vue 2.0.0 beta版本
首先找到入口函数, 看挂载方式
在这里插入图片描述
这一块是我们想要的

然后去上面找引用关系,也就是message和Modal.info的引用
奈何水平有限, 真看不懂message的代码, 于是挑了Modal.info的实现方式来实现


直接跳转到这里
这个文件不长,慢慢从上面往下看, 定义了close,update,destroyrender方法
render中的代码怎么这么熟悉, 这不就是cli创建出来的main.js中的代码或者文档中起步的实例代码吗
在这里插入图片描述
好的, 我们接下来捋一下思路
在2.x中的实现方式为:

  1. 使用vue.extend实例化对象
  2. 将实例化的对象插入到body中

在3.x中无非就是将extend换为creatApp

直接上代码

// loading.vue
<template>
	<teleport v-if="show" to="body">
		<div class="loading">
			loding...
		</div>
	</teleport>

</template>

<script>
    export default {
        name: "d-loading",
		    props:["parentdom"],
        data() {
            return {
                show: false
            }
        },
        methods: {
            init() {
                this.show = true;
                return this
            },
            hidden() {
                this.show = false;
                // 删除父元素
                this.parentdom.parentElement.removeChild(this.parentdom);
            }
        }
    }
</script>

<style scoped lang="scss">
	.loading {
		width: 100%;
		height: 100%;
		position: fixed;
		top: 0;
		right: 0;
		background: #fff;
		text-align: center;
		z-index: 9999;
	}
</style>
//loading.js loading组件的注册文件
import loading from "./d-loading"
import {createApp} from "vue"
function loading() {
  // 创建一个div包裹loading元素
  let div = document.createElement("div")
  // 将创建好的div插入到body中
  document.querySelector("body").appendChild(div);
  // 在创建好的div中重新实例化一个vue实例
  let loadingEl = createApp(loading, {parentdom: div})
  // 保存loading对象
  let loadingVm = loadingEl.mount(div)
  // 显示loading
  loadingVm.init();
  return () => {
  	  // 销毁实例
      loadingEl.unmount(div)
      // 销毁loading
      loadingVm.hidden();
  };
}

export default {
  install: (app) => {
    // 挂载到this.$loading中
    app.config.globalProperties.$loading = loading
  }
}
// main.js
import loading from "./components/loading";

createApp(App)
	.use(store)
	.use(router)
	.use(loading)
	.mount('#app')
//调用方式
showLoading(){
  console.log(this.$loading)
  let l = this.$loading()

  setTimeout(()=>{
      l()
  },5000)
}
Logo

前往低代码交流专区

更多推荐