vue中v-loading指令的实现
2021-03-29 17:57

v-loading指令实现代码

import Vue from 'vue';
Vue.directive('loading',{
    bind:function(el,binding){
        let div = document.createElement('div');
        div.className="vloading-mask";
        let posi = window.getComputedStyle(el,null).getPropertyValue('position');
        if(posi == "static" || posi == ""){
            el.style.position = "relative";
        }
        div.style.display="none";
        el.appendChild(div);
        el.loaddiv = div;
        if(binding.value == true){
            div.style.display="block";
        }else {
            div.style.display="none";
        }
    },
    inserted:function(el){
        
    },
    update:function(el,binding){
        let posi = window.getComputedStyle(el,null).getPropertyValue('position');
        if(posi == "static"){
            el.style.position = "relative";
        }
        let div = el.loaddiv;
        if(binding.value == true){
            div.style.display="block";
        }else {
            div.style.display="none";
        }
    },
    unbind:function(el){
        let div = el.loaddiv;
        el.removeChild(div);
        el.dataset.div = null;
    }
})

v-loading指令实现代码还是很简短的。我们只需在binding回调中创建一个元素,作为模板,覆盖整个元素,在模板中间添加一个loading的动画图标和相应的文字即可。然后再update的回调时修改起展现和隐藏,在unbind时将创建的dom元素删除。

.vloading-mask{position:absolute;z-index: 500;left:0;top:0;right:0;bottom:0;text-align:center;background:url(~@/assets/loading.svg) center center/ 40px 40px no-repeat,rgba(218,218,218,0.6);}

v-loading添加样式,然后再添加一个svg动画图片即可。

loading.svg内容如下:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: transparent; display: block; shape-rendering: auto;" width="121px" height="121px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="translate(20 20)">
  <rect x="-15" y="-15" width="30" height="30" fill="#3be8b0">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.425531914893617s"></animateTransform>
  </rect></g>
<g transform="translate(50 20)">
  <rect x="-15" y="-15" width="30" height="30" fill="#1aafd0">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.3191489361702127s"></animateTransform>
  </rect></g>
<g transform="translate(80 20)">
  <rect x="-15" y="-15" width="30" height="30" fill="#6a67ce">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.2127659574468085s"></animateTransform>
  </rect></g>
<g transform="translate(20 50)">
  <rect x="-15" y="-15" width="30" height="30" fill="#1aafd0">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.3191489361702127s"></animateTransform>
  </rect></g>
<g transform="translate(50 50)">
  <rect x="-15" y="-15" width="30" height="30" fill="#6a67ce">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.2127659574468085s"></animateTransform>
  </rect></g>
<g transform="translate(80 50)">
  <rect x="-15" y="-15" width="30" height="30" fill="#ffb900">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.10638297872340426s"></animateTransform>
  </rect></g>
<g transform="translate(20 80)">
  <rect x="-15" y="-15" width="30" height="30" fill="#6a67ce">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.2127659574468085s"></animateTransform>
  </rect></g>
<g transform="translate(50 80)">
  <rect x="-15" y="-15" width="30" height="30" fill="#ffb900">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="-0.10638297872340426s"></animateTransform>
  </rect></g>
<g transform="translate(80 80)">
  <rect x="-15" y="-15" width="30" height="30" fill="#fc636b">
    <animateTransform attributeName="transform" type="scale" repeatCount="indefinite" calcMode="spline" dur="1.0638297872340425s" values="1;1;0.2;1;1" keyTimes="0;0.2;0.5;0.8;1" keySplines="0.5 0.5 0.5 0.5;0 0.1 0.9 1;0.1 0 1 0.9;0.5 0.5 0.5 0.5" begin="0s"></animateTransform>
  </rect></g>

<!-- [ldio] generated by https://loading.io/ --></svg>

还可以轻松的改变svg的颜色,大小等特性。

使用跟element的v-loading一样方便。

<div class="pto-cont" v-loading="loading">
</div>

只要目标元素有高度,loading图片就能在其中间显示。我们只需要在ajax请求前设置loading=false;在ajax请求完成后设置loading = true;

image.png

效果如上。

可优化点

可以修改loading样式,文案,适配自己的项目,还可以通过跟指令设置一些参数,如text,icon等来增加指令的灵活性。

原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(1213)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1