vue自定义指令v-loading

本文介绍了如何在Vue项目中创建自定义的loading动画,以替代elementUI或antdesign等UI框架提供的默认loading。通过创建指令、组件和注册插件,实现了高度定制化的加载效果,包括动画样式和文字内容。详细步骤包括创建文件结构、编写loading组件、实现自定义指令以及在main.js中注册和使用。
摘要由CSDN通过智能技术生成

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>

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Vue.js的v-loading指令是一种自定义指令,用于在异步操作期间显示加载状态。通过使用v-loading指令,我们可以轻松地在Vue.js应用程序中实现加载状态的显示和隐藏,提升用户体验。 v-loading指令的原理是,在指令绑定的元素上添加一个遮罩层,并在遮罩层上显示加载状态的UI。当异步操作完成时,遮罩层和加载状态UI会被移除。 下面是一个简单的v-loading指令的实现: ```javascript Vue.directive('loading', { bind: function (el, binding) { const mask = document.createElement('div') mask.className = 'loading-mask' const spinner = document.createElement('div') spinner.className = 'loading-spinner' mask.appendChild(spinner) el.appendChild(mask) el.__loading__ = mask if (binding.value) { el.classList.add('relative') mask.classList.add('show') } else { el.classList.remove('relative') mask.classList.remove('show') } }, update: function (el, binding) { if (binding.value) { el.classList.add('relative') el.__loading__.classList.add('show') } else { el.classList.remove('relative') el.__loading__.classList.remove('show') } }, unbind: function (el) { el.removeChild(el.__loading__) delete el.__loading__ } }) ``` 这个指令会为绑定它的元素添加一个遮罩层和加载状态UI,并在元素的`v-loading`属性值发生变化时显示或隐藏遮罩层和加载状态UI。我们可以在模板中使用这个指令来显示加载状态,例如: ```html <div v-loading="loading"> <!-- 异步操作的内容 --> </div> ``` 这个指令的样式可以根据项目需求自行修改,下面是一个简单的CSS样式示例: ```css .loading-mask { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, .5); display: none; } .loading-spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 4px solid #fff; border-top-color: transparent; border-radius: 50%; width: 32px; height: 32px; animation: spin .8s linear infinite; } .show { display: block; } .relative { position: relative; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } ```
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值