elementUI或者antdesign上的loading拿来就用简单无脑,以前我也是一直在用UI框架自带的loading,后来用的发现好呆板,一点也不炫酷,于是就自定义了,废话不说了直接看效果图

1. 创建文件

1.在 src目录下创建一个directiveLoading文件夹,然后这个文件夹下创建1个loading文件夹和index.js文件,loading文件夹下分别创建Loading.vueindex.js文件。
directiveLoading的index.js文件用来暴露安装插件接口。如下所示

import Vue from 'vue'
import Loading from './loading'
export default {
  install(Vue) {
    Vue.directive('myLoading', Loading)
  }
}

 2.loading.vue,用来插入到自定义指令的目标元素中,就是写静态页面可以自定义样式和一些炫酷的东东。

<template>
    <div class="htmleaf-container">
      <div class="loader">
        <div class="my-loading"></div>
        <div class="my-loading-text">加载中...</div>
      </div>
    </div>
</template>

<script>
export default {
  name: "",
  data() {
    return {};
  },
  props: {},
  components: {},
  methods: {},
  created() {},
  mounted() {},
  beforeDestroy() {},
};
</script>

<style lang ="scss"  scoped>
/* .container-loading {
  height: 100%;
  width: 100%;
} */
.htmleaf-container {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  font-size: 12px;

  min-height: 60px;
  background-color: rgba(255, 255, 255, 0.8);
}

.loader {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 60px;
}

.loader .my-loading {
  position: relative;
  width: 100%;
  height: 10px;
  border: 1px solid #30b08f;
  border-radius: 10px;
  animation: turn 1s linear 0.42s infinite;
}

.loader .my-loading:before {
  content: "";
  display: block;
  position: absolute;
  width: 0%;
  height: 100%;
  background: #30b08f;
  box-shadow: 10px 0px 15px 0px #30b08f;
  animation: load .5s linear infinite;
}

.loader .my-loading-text {
  width: 100%;
  position: absolute;
  top: 10px;
  color: #30b08f;
  text-align: center;
  animation: bounce .5s linear infinite;
}

@keyframes load {
  0% {
    width: 0%;
  }

  87.5%,
  100% {
    width: 100%;
  }
}

@keyframes turn {
  0% {
    transform: rotateY(0deg);
  }

  6.25%,
  50% {
    transform: rotateY(180deg);
  }

  56.25%,
  100% {
    transform: rotateY(360deg);
  }
}

@keyframes bounce {
  0%,
  100% {
    top: 10px;
  }

  12.5% {
    top: 30px;
  }
}
</style>

2. 实现自定义指令

       在loading文件夹的index.js写

import Vue from 'vue'
import Loading from './Loading.vue'
/**
 * Vue.extend 接受参数并返回一个构造器,new 该构造器可以返回一个组件实例
 * 当我们 new Mask() 的时候,把该组件实例挂载到一个 div 上
 **/
const Mask = Vue.extend(Loading)

// 更新是否显示
const toggleLoading = (el, binding) => {
  if (binding.value) {
    Vue.nextTick(() => {
      // 控制loading组件显示
      el.instance.visible = true
      el.style.position = 'relative'
      // 插入到目标元素
      insertDom(el, el)
    })
  } else {
    el.instance.visible = false
    el.style.position = 'static'
    el.mask && el.mask.parentNode && el.mask.parentNode.removeChild(el.mask)
  }
}

// 插入到目标元素
const insertDom = (parent, el) => {
  parent.appendChild(el.mask)
}

export default {
  // 第一次绑定到元素时调用
  bind: function(el, binding, vnode) {
    const mask = new Mask({
      el: document.createElement('div'),
      data() {}
    })
    // 用一个变量接住mask实例
    el.instance = mask
    el.mask = mask.$el
    el.maskStyle = {}
    binding.value && toggleLoading(el, binding)
  },
  // 所在组件的 VNode 更新时调用--比较更新前后的值
  update: function(el, binding) {
    if (binding.oldValue !== binding.value) {
      toggleLoading(el, binding)
    }
  },
  // 指令与元素解绑时调用
  unbind: function(el, binding) {
    el.instance && el.instance.$destroy()
  }
}

3. 注册插件

        在main.js里引入

import DirectiveLoading from './directiveLoading' //自定义loading
Vue.use( DirectiveLoading )

4. 插件使用

 <div v-myLoading="dayLoading">
        就是这么简单
    </div>

Logo

前往低代码交流专区

更多推荐