美文网首页12月vue让前端飞
vue3.x全局$toast、$message、$loading

vue3.x全局$toast、$message、$loading

作者: 学杂不精 | 来源:发表于2021-10-20 12:32 被阅读0次

    有时候我们需要使用一些类似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)
    

    setup内使用

    import { getCurrentInstance} from 'vue'
    
    setup() {
      const { proxy } = getCurrentInstance();
      return {
        loadingEvent: () => {
          proxy.$loading.show()
          setTimeout(() => {
            proxy.$loading.hide()
          }, 2000)
        }
      }
    }
    

    vue3.x全局插件和组件

    相关文章

      网友评论

        本文标题:vue3.x全局$toast、$message、$loading

        本文链接:https://www.haomeiwen.com/subject/cigaoltx.html