美文网首页lodash
vue 实现全局使用的loading组件(使用Vue.exten

vue 实现全局使用的loading组件(使用Vue.exten

作者: 东扯葫芦西扯瓜 | 来源:发表于2021-06-13 09:47 被阅读0次

    vue 实现全局使用的loading组件(使用Vue.extend)

    在开发中,如果项目比较复杂,那么页面加载往往会有一个小空白时间。当然了,页面加载速度这些我们必须要去优化。但若有时候网络不好了什么的,总之免不了会出现白屏。为了不让用户的内心在这段时间内过于寂寞,我们往往需要给页面加上 loading 小圈圈,告诉用户:我们正在努力拽数据呢,亲,稍等哈~~

    实现思路

    其实,写个loadign页面很简单,关键的是如何让使用起来更简单。

    思路一:可能我们一开始最容易想起来的就是,吧loading抽成一个组件,那个页面要用,那个页面引入就好了,然后注册组件,用v-if或者v-show显示隐藏。这没啥毛病,就是感觉麻烦了点,凭什么每个页面都要去引入?这组件用的频率高,列表加载,点击保存,估计我们都会用。

    思路二:那既然使用频率高,何不将组件做成全局注册组件?这样就省去了每个组件引用的代码。这比思路一要更进一步了,但是,这样我们就满足了吗?NO! NO! NO! 这不是一个优雅的程序员的风格啊。

    假如你和我一样,都不是神马大佬级别人物。如果同样有这种需求,而又一时想不到好办法,咋办?
    抄呗。咳咳,说的太直接了点,应该叫借鉴,擅长于从别人的代码里面学习也是一种能力。
    使用vue开发的童鞋,相比大部分都使用过element-ui,当然element-ui也有loading组件,你会发现使用时loading,confirm这些组件,都是可以用this访问的,这样调用起来是不是很方便?

    点开loading组件源码,我们找到了实现的关键点。其实就是下面这代码

    const LoadingConstructor = Vue.extend(loadingVue);
    
    
    LoadingConstructor.prototype.close = function() {
      if (this.fullscreen) {
        fullscreenLoading = undefined;
      }
      afterLeave(this, _ => {
        const target = this.fullscreen || this.body
          ? document.body
          : this.target;
        removeClass(target, 'el-loading-parent--relative');
        removeClass(target, 'el-loading-parent--hidden');
        if (this.$el && this.$el.parentNode) {
          this.$el.parentNode.removeChild(this.$el);
        }
        this.$destroy();
      }, 300);
      this.visible = false;
    };
    

    其实就是,使用vue.extend创建构造器,然后在构造器下挂函数就好了。

    官方对vue.extend解释也很简单:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数

    好,这就是我们的思路三了。有了思路,我们就可以实现了,这里我们不需要像elemenet-ui那么复杂,简单点。

    剩下的就直接上代码了哈。起个名字吧,叫lm-loading。
    lm-loading.vue

    <template>
      <div class="loadingBox rowCenter" v-if="visible">
        <i class="el-icon-loading font32 gray666"></i>
      </div>
    </template>
    
    <script>
    export default {
        name: "LmLoading",
    }
    </script>
    
    

    入口文件index.js

    import Vue from 'vue'
    import lmLoading from './lm-loading'
    const LmLoadingConstructor=Vue.extend(lmLoading)
    let instance
    const initInstance = () => {
      instance = new LmLoadingConstructor({
        el: document.createElement('div'),
        data(){
          return {
            visible: false,
          }
        }
      })
    }
    const LmLoading=function (){
      if (!instance) {
        initInstance()
      }
    }
    LmLoading.show=function (timeout){
      return new Promise((resolve,reject)=>{
        document.body.appendChild(instance.$el)
        instance.visible = true
        if(typeof timeout==='number'){
          let timeNum=setTimeout(()=>{
            clearTimeout(timeNum)
            instance.visible=false
          },timeout)
        }
        resolve(true)
      })
    }
    LmLoading.hidden=function (){
      instance.visible =false
    }
    export default LmLoading
    
    

    如此,调用也很简单

    在main.js里面引入

    import LmLoading from 'lm-loading'
    Vue.use(LmLoading)
    Vue.prototype.$lmLoading=LmLoading

    使用

    this.$lmLoading.show()

    this.$lmLoading.hidden()

    相关文章

      网友评论

        本文标题:vue 实现全局使用的loading组件(使用Vue.exten

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