指令模式(蒙版)fullscreenBoolean v-dht-loading.fullscreen在非全屏模式下,dom没有渲染完成下会导致元素顶部对齐 
backgroundString0, 0, 0, 0.5  
textString加载中...  
iconSrcString默认加载图修改加载提示图片 
iconWidthString 图片宽度 
iconHeightString 图片高度 
colorString 字体颜色 
fontSizeString 字体大小 

指令模式更难处理一些东西,但是基本上是差不多的。

模板代码部分:

<template>
  <div
    :class="fullscreen ? 'dhtMask-FullScreen' : 'dhtMask'"
    :style="{
      zIndex: this.$dhtUI.zIndex,
      background: 'rgba(' + background + ')',
      fontSize: fontSize + 'px',
      color: color
    }"
  >
    <img
      class="dht-loading-icon"
      :src="iconSrc"
      alt="loading"
      :style="{ width: iconWidth + 'px', height: iconHeight + 'px' }"
    />
    <span>{{ text }}</span>
  </div>
</template>

<script>
export default {
  name: "dhtMask",
  data() {
    return {
      fullscreen: false,
      background: "0, 0, 0, 0.5",
      text: "加载中…",
      iconSrc: null,
      iconWidth: null,
      iconHeight: null,
      color: null,
      fontSize: null
    };
  },
  beforeCreate() {},
  created() {},
  beforeMount() {},
  mounted() {
    if (this.fullscreen) {
      document.body.style.overflow = "hidden";
    }
  },
  beforeUpdate() {},
  updated() {},
  activated() {},
  deactivated() {},
  beforeDestroy() {},
  destroyed() {
    document.body.style.overflowX = "hidden";
  },
  errorCaptured() {},
  methods: {}
};
</script>

<style lang="scss">
.dhtMask {
  position: absolute;
  z-index: 2000;
  background: rgba(0, 0, 0, 0.5);
  width: 100%;
  height: 100%;
  color: #ffffff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 12px;
  flex-flow: column;
}
.dhtMask-FullScreen {
  @extend .dhtMask;
  width: 100vw;
  height: 100vh;
  top: 0;
  background: (0, 0, 0, 0.5);
}
.dht-loading-icon {
  width: 25px;
  height: 25px;
  object-fit: cover;
  margin-bottom: 5px;
  animation: dht-rotate 2s linear infinite;
  @keyframes dht-rotate {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }
}
</style>

指令代码部分 

import vue from "vue";
import maskLoading from "./mask.vue";

const Mask = vue.extend(maskLoading);

//主函数
const directive = () => {
  //蒙版操作更新
  const toggleLoading = function(el, binding) {
    //console.log(binding);
    if (binding.value) {
      vue.nextTick(() => {
        if (binding.modifiers.fullscreen) {
          //全屏情况下
          //el.instance.fullscreen = true;
          //document.body.style.overflow = "hidden";
          document.body.appendChild(el.mask);
        } else {
          //el.instance.fullscreen = false;
          //非全屏情况下
          let height = el.clientHeight; //当前元素高度
          let width = el.clientWidth; //当前元素宽度
          let offsetTop = el.offsetTop; //当前元素距离顶部距离
          //给蒙版赋值
          el.mask.style.top = offsetTop + "px";
          el.mask.style.height = height + "px";
          el.mask.style.width = width + "px";
          //console.log(offsetTop);
          el.appendChild(el.mask);
        }
      });
    } else {
      //移除节点
      el.mask && el.mask.parentNode && el.mask.parentNode.removeChild(el.mask);
      el.instance && el.instance.$destroy();
    }
  };
  //let timer = "";
  vue.directive("dhtLoading", {
    //只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    bind(el, binding) {
      //console.log(el, binding, vnode);
      let background = binding.value.background,
        text = binding.value.text,
        iconSrc = binding.value.iconSrc,
        iconWidth = binding.value.iconWidth,
        iconHeight = binding.value.iconHeight,
        color = binding.value.color,
        fontSize = binding.value.fontSize;
      const mask = new Mask({
        el: document.createElement("div"),
        data: {
          fullscreen: !!binding.modifiers.fullscreen,
          background: background ? background : "0, 0, 0, 0.5",
          text: text ? text : "加载中…",
          iconSrc: iconSrc ? iconSrc : require("../../style/img/loading.png"),
          iconWidth: iconWidth ? iconWidth : null,
          iconHeight: iconHeight ? iconHeight : null,
          color: color ? color : null,
          fontSize: fontSize ? fontSize : null
        }
      });
      el.instance = mask; //将mask存入
      el.mask = mask.$el; //dom存入,方便获取
      toggleLoading(el, binding);
    },
    // 当被绑定的元素插入到 DOM 中时……
    //被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    // eslint-disable-next-line no-unused-vars
    inserted: function(el, binding, vnode, oldVnode) {
      //console.log("元素插入的时候");
    },
    //所在组件的 VNode 更新时调用
    update(el, binding) {
      //console.log("更新了", binding);
      if (binding.oldValue !== binding.value) {
        toggleLoading(el, binding);
      }
    },
    //指令所在组件的 VNode 及其子 VNode 全部更新后调用
    componentUpdated() {
      //console.log("渲染完成了");
    },
    //只调用一次,指令与元素解绑时调用
    unbind(el) {
      //console.log("解绑了");
      //不知道指令如何解绑,先写着
      el.mask && el.mask.parentNode && el.mask.parentNode.removeChild(el.mask);
      el.instance && el.instance.$destroy();
    }
  });
};

export default directive;

 

Logo

前往低代码交流专区

更多推荐