因为我们第一次发送请求给后端的时候比较慢,有时候也不知道什么时候后端返回了请求,所以这里我设置了一个加载动画,能够起到很好的引导用户的作用。
正常情况的页面是这样的
加载中的时候是这样
使用的是ElementUI的v-loading:
<div v-loading="isLoading" element-loading-text="加载中" element-loading-background="rgba(180, 180, 180, 0.8)"
class="chatHome">
但是他默认的很丑,覆盖区域也不对,所以我想自定义一个加载组件。
首先在src文件夹下创建一个directive文件夹去存放loading相关的代码,在loading.vue文件中去写相关的样式操作
<template>
<div v-show="visible" class="loading-wrap">
<div class="loading-box">
<div class="loading-add"></div>
<div class="loading-txt">加载中...</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
visible:false
}
}
}
</script>
<style lang="less" scoped>
.loading-wrap{
white-space: nowrap;
}
.loading-box{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%);
font-size: 16px;
white-space: nowrap;
user-select: none;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.loading-add{
width: 30px;
height: 30px;
border: 2px solid #F53939 ;
border-top-color: transparent;
border-radius: 100%;
animation: add infinite 0.75s linear;
}
@keyframes add {
0% {
transform: rotateZ(0);
}
100% {
transform: rotateZ(360deg);
}
}
.loading-txt {
margin-top: 5px;
color: #F53939 ;
}
</style>
然后再同级目录创建一个loading.js
import Vue from "vue";
import Loading from "./loading.vue";
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:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
bind: function (el,binding,vnode) {
// new Mask()的时候,把该组件实例挂载到一个div上
const mask = new Mask({
el: document.createElement('div'),
data() {return {}}
})
el.instance = mask;
el.mask = mask.$el;
binding.value && toggleLoading(el,binding)
},
update: function (el, binding) {
if(binding.oldValue !== binding.value) {
toggleLoading(el, binding)
}
},
unbind: function (el, binding) {
el.instance && el.instance.$destroy()
}
}
Vue.extend 返回一个构造器,new该构造器可以返回一个组件实例,new Mask()的时候,把该组件实例挂载到一个div上。 在bing函数先去打印一下el看一下都是什么:
发现是一个空的div,此时需要用一个变量去接住这个实例,el.instance = mask,- 接下来判断 value 是否为 true ,如果是 true 则执行 toggleLoading ,toggleLoading 方法用来控制是否显示 loading.vue 组件中的 visible变量,并且如果 value是true则插入到目标元素。
在directive文件夹下创建index.js
import loading from './loading';
export default {
install(Vue) {
Vue.directive("loading",loading)
}
}
main.js中全局注册
import loading from './directives/loading'
Vue.use(loading)
这样在项目里面就可以直接使用v-loading,自定义的效果覆盖了原来自带的。
<div v-loading="true"></div>
参考文章
https://juejin.cn/post/7052150837828812836