vue3.x全局$toast、$message、$loading等js插件

有时候我们需要使用一些类似toast,messge、loading这些跟js交互很频繁的插件,vue3.x这类插件的定义跟vue2.x插件稍大,而且相对变得复杂了一点点。

第一种、需要时创建,用完移除

这种做法相对损耗性能,当一些显示隐藏频率不是特别高的插件可以如此封装。
1、新建loading.vue文件

<template>
  <div class="loading">
    加载中...
  </div>
</template>

<script>
  export default {
    name: "loading",
  }
</script>

<style scoped>
  .loading {
    position: fixed;
    left: 50%;
    top: 50%;
    background-color: rgba(0, 0, 0, 0.2);
    color: white;
    transform: translate(-50%, -50%);
    border-radius: 4px;
    padding: 8px 10px;
  }
</style>

2、同级目录新建index.js文件

import { createApp } from "vue"

import Loading from './loading.vue'

export default {
  instance: null,
  parent: null,
  times: 0, 
  // 为了保证多个同时loading的时候,只显示一个,并且需要全部close之后才消失
  open() {
    if (this.times == 0) {
      this.instance = createApp(Loading)
      this.parent = document.createElement("div")
      let appDom = document.getElementById('app')
      appDom.appendChild(this.parent)
      this.instance.mount(this.parent)
    }
    this.times ++
  },
  close() {
    this.times --
    if (this.times <= 0) {
      this.times = 0
      let appDom = document.getElementById('app')
      this.instance.unmount(this.parent)
      appDom.removeChild(this.parent)
    }
  }
};

3、插件全局引入

import loading from '@/components/loading/index'
app.config.globalProperties.$loading = loading;

当然步骤2可以抛出install函数,然后main.js里面用use来全局载入。这样使用会导致我们不能使用this的地方不太好调用loading。

4、组件内使用

this.$loading.open()
setTimeout(() => {
  this.$loading.close()
}, 2000)

第二种,一直存在,只控制显示隐藏

1、新建loading.vue文件

<template>
  <div class="loading" v-show="visible">
    加载中...
  </div>
</template>

<script>
  export default {
    name: "loading",
    data() {
      return {
        visible: false
      };
    },
    methods: {
      show() {
        this.visible = true
      },
      hide() {
        this.visible = false
      }
    }
  }
</script>

<style scoped>
  .loading {
    position: fixed;
    left: 50%;
    top: 50%;
    background-color: rgba(0, 0, 0, 0.2);
    color: white;
    transform: translate(-50%, -50%);
    border-radius: 4px;
    padding: 8px 10px;
  }
</style>

2、同级目录新建index.js文件

import { createApp } from "vue"

import Loading from './loading.vue'

export default {
  loading: null,
  install(Vue) {
    if (this.loading) {
      // 防止多次载入
      Vue.config.globalProperties.$loading = this.loading;
      return ;
    }
    let instance = createApp(Loading);
    let parent = document.createElement("div")
    let bodyDom = document.body
    // 这里需要注意,大概率app还没有mount,导致获取不到app节点,所以想挂载到app上,需要保证app已经创建。
    bodyDom.appendChild(parent)
    this.loading = instance.mount(parent)

    Vue.config.globalProperties.$loading = this.loading;
  }
};

3、插件全局引入

import Loading from '@/components/loading/index'
app.use(Loading)

4、组件内使用

this.$loading.show()
setTimeout(() => {
  this.$loading.hide()
}, 2000)

vue3.x全局插件和组件

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):