在我们的实际开发中,项目当中需要加载一些信息的时候,且不能操作,这样就需要在上面放个遮罩层显示加载中,如果我们每个框里面加一个加载标签的话,这样会很麻烦,也不好管理

这就需要我们自定义指令v-loading

首先我们创建文件

在src文件下建directive文件夹,里面创建index.js,loading文件夹里面创建Loading.vue和index.js
loading.vue组件,用来插入到自定义指令的目标元素中
// src/directive/loading/Loading.vue
<template>
	<div v-show="visible" class="loading-wrap">
		<div class="loading-box">加载中...</div>
	</div>
</template>

<script>
export default {
	data() {
		return {
			visible: true
		}
	}
}
</script>
<style lang="less" scoped>
.loading-wrap {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.5);
}
.loading-box {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 100px;
	transform: translate(-50%, -50%);
}
</style>
index.js编写自定义指令
// src/directive/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
      // 插入到目标元素
      insertDom(el, el, binding)
    })
  } else {
    el.instance.visible = false
  }
}

 插入到目标元素
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()
  }
}
index.js文件用来暴露安装插件接口
// src/directive/index.js
import Loading from './loading'
export default {
  install (Vue) {
    Vue.directive('loading', Loading)
  }
}
最后在main.js中引用这个插件就可以了
// main.js
import Directive from './directive'
// 使用插件
Vue.use(Directive)
这样我们就可以在页面当中调用v-loading这个指令了
<template>
	<div class="hello">
		<div class="loading-box" v-loading='loading'></div>
		<button @click='loadingBtn'>显示隐藏</button>
	</div>
</template>

<script>
export default {
	name: 'loading',
	data() {
		return {
			loading: true
		}
	},
	methods: {
		loadingBtn() {
			this.loading = !this.loading
		}
	}


}
</script>
<style lang='less' scoped>
.loading-box {
	width: 400px;
	height: 400px;
	border: 1px solid #eee;
	position: relative;
}
</style>

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐