记录--Vue自定义指令实现加载中效果v-load(不使用Vue.extend)
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
网站效果演示:ashuai.work:8888/#/myLoad
GitHub仓库地址代码:github.com/shuirongshu…
加载中思路分析
实现加载中效果,一般有两种方式:
- 第一种是:搞一个
load组件
,然后使用Vue.extend()方法
去继承一个加载组件去使用,比如笔者的这篇文章:juejin.cn/post/702172… - 第二种是:直接使用指令去在需要加载的
dom
上去创建一个加载中的dom
元素,并指定相应的样式即可。本篇文章说的是第二种。
我们先看一下效果图
v-load效果图
实现步骤一:加上自定义指令
假设我有一个dom元素,我给其加上一个自定义的指令v-load="loading"
,绑定一个具体的布尔值loading
,用于控制开启加载中和关闭加载中
<div class="box" v-load="loading">111</div>loading: true.box {width: 160px;height: 80px;border: 2px solid #666;
}
接下来,我就要在自定义指令的相关钩子函数中去操作这个dom
元素。
关于自定义指令的入门基础知识可以看官方文档,或者参见笔者之前的关于自定义指令的文章:juejin.cn/post/702960…
实现步骤二:给目标元素创建一个子元素dom用于加载
在自定义指令的初始化bind钩子
函数中,我们可以拿到这个dom
元素,首先给这个目标元素开始相对定位,让用于加载中的子元素dom
去绝对定位,以这个相对定位的父元素进行参考
bind(el, binding) {const target = el;// 父元素相对定位target.style.position = "relative";// 子元素遮罩层部分let loadChild = document.createElement("div");loadChild.className = "loadClass";
}
上述代码中给加载中的子元素loadChild
指定一个样式类名loadClass
在这里小伙伴可能有疑问了,这个自定义指令的样式怎么写呢?自定义指令中也没有style
标签啊?
是的,自定义指令中不能直接写样式,不过没关系,我们可以先写好一个css
样式,然后引入过来使用啊,如下:
// 引入拆分的样式,便于自定义指令中使用
import './index.css'bind(el, binding) {......loadChild.className = "loadClass";
}
这样的话,className
的样式,可以在引入的同级目录下的./index.css
文件中设置了,loadClass
样式如下:
.loadClass {/* 宽高百分百 */position: absolute;top: 0;bottom: 0;left: 0;right: 0;/* 默认背景色和颜色 */background-color: rgba(255, 255, 255, 0.99);color: #0b6ed0;/* 透明度过渡使用搭配display:none; */opacity: 0.8;transition: all 0.3s;/* 居中 */ display: flex;align-items: center;justify-content: center;
}
注意,加载中效果开启和消失,不用使用vue
自带的过渡组件transition
,咱们可以使用透明度
搭配搭配display:none;
去设置
注意,加载中要以父元素为边界去控制,可不能满屏加载哦
然后初始化的时候,看看v-load
绑定的值是true
还是false
,同时加上一个用于隐藏的类名:load-hide
。再把这个加载中的dom
元素追加到目标父元素身上。
loadChild.classList.add('load-hide') // 添加类名
target.appendChild(loadChild); // 追加加载中子元素/* 通过透明度实现过渡动画 */
.load-hide {opacity: 0;
}
这样的话,初始化的加载中就做好了。v-load
绑定的值是false
的时,就隐藏之
实现步骤三:当组件更新时,去添加或移除这个load-hide类名
componentUpdated(el, binding, vnode, oldVnode) {let flag = binding.valuelet loadChild = el.querySelector('.loadClass')if (flag) { // v-load绑定的值为true,就移除这个类名,就能看到了loadChild.style.display = 'flex'setTimeout(() => {loadChild.classList.remove('load-hide')}, 0);} else { // 绑定的值为false时,再添加这个类名,同时隐藏domloadChild.classList.add('load-hide')setTimeout(() => {loadChild.style.display = 'none'}, 360);}},
注意上述代码中为啥不直接隐藏,而是使用定时器延长360毫秒
再去隐藏,因为笔者设置的加载dom
的过渡时间是0.3秒
,即要等到透明度过渡完了以后,再隐藏加载中dom
,这样看着就自然一些了。
.loadClass { transition: all 0.3s; }
到这里,咱们的v-load
自定义指令的加载中效果,就初步完成了。不过功能有点少,自定义加载中我还想,去动态控制:
- 自定义加载图标名
- 自定义加载文字
- 自定义加载文字颜色
- 自定义加载背景色
那这样怎么办呢?
实现步骤四:优化自定义指令,支持传入更多的参数
此时,我的v-load
自定义指令,就不用绑定一个布尔值了。可以考虑绑定一个对象啊,通过控制这个对象的具体值,来动态控制加载中的效果。
- 原来自定义指令绑定:
v-load = loading
//typeof loading == 'boolean'
- 现在自定义指令绑定:
v-load = loading2
//typeof loading2 == 'object'
<div class="box" v-load="loading2">222</div>// 如果想要有更多的配置项,就传一个对象,注意要指定字段
loading2: {value: true,icon: "el-icon-eleme", // 自定义加载图标名text: "客官稍等哦...", // 自定义加载文字color: "red", // 自定义加载文字颜色bgColor: "#baf", // 自定义加载背景色
}
传参指定相应字段,自定义指令中接参,就要在相关的钩子中去接收并处理这些参数。
如何处理这些参数?
- v-load绑定的值的类型的判断,是布尔值,还是对象,执行不同的操作
- 使用原生js的方式去,创造dom元素、给dom元素指定类名(或添加删除类名)
- 考虑到性能缘故,可以使用文档碎片优化
document.createDocumentFragment()
- 最后丢入遮罩层dom内部即可
完整代码
自定义指令样式文件index.css
.loadClass {/* 宽高百分百 */position: absolute;top: 0;bottom: 0;left: 0;right: 0;/* 默认背景色和颜色 */background-color: rgba(255, 255, 255, 0.99);color: #0b6ed0;/* 透明度过渡使用搭配display:none; */opacity: 0.8;transition: all 0.3s;/* 禁止文字选择 */user-select: none;display: flex;align-items: center;justify-content: center;
}/* 通过透明度实现过渡动画 */
.load-hide {opacity: 0;
}.loadClass>i {margin-right: 4px;
}
自定义指令的js文件index.js
注意,自定义指令还需要注册一下才能使用哦
// 引入拆分的样式,便于自定义指令中使用
import './index.css'
export default {// 初始化绑定dom钩子函数bind(el, binding) {const target = el;// 传参类型判断变量控制let flag;let isObj;if (typeof binding.value == 'boolean') {flag = binding.valueisObj = false}if (typeof binding.value == 'object') {flag = binding.value.valueisObj = true}// 有dom元素才去做操作if (target) {// 父元素相对定位target.style.position = "relative";// 子元素遮罩层部分let loadChild = document.createElement("div");loadChild.className = "loadClass";// 创建文档碎片性能稍微优化一点点let fragment = document.createDocumentFragment()// 孙子元素1加载图标部分let iSun = document.createElement("i");iSun.className = isObj ? binding.value.icon : "el-icon-loading";// 孙子元素2文字提示部分let spanSun = document.createElement("span");spanSun.innerHTML = isObj ? binding.value.text : '加载中...'// 使用文档碎片将iSun和spanSun装起来fragment.appendChild(iSun);fragment.appendChild(spanSun);// 将文档碎片丢入子元素遮罩层内loadChild.appendChild(fragment);// 样式判断设置if (isObj) {loadChild.style.color = binding.value.colorloadChild.style.backgroundColor = binding.value.bgColor}// 若为false,就隐藏if (!flag) {loadChild.classList.add('load-hide')loadChild.style.display = 'none'}// 父元素添加子元素遮罩层使用target.appendChild(loadChild);}},// dom组件更新操作控制显示和隐藏componentUpdated(el, binding, vnode, oldVnode) {let flag = typeof binding.value == 'boolean' ? binding.value : binding.value.valuelet loadChild = el.querySelector('.loadClass')if (flag) {loadChild.style.display = 'flex'setTimeout(() => {loadChild.classList.remove('load-hide')}, 0);} else {loadChild.classList.add('load-hide')setTimeout(() => {loadChild.style.display = 'none'}, 360);}},
}
使用自定义load指令的地方
<template><div><h3>指令方式加载中...</h3><br /><button @click="loadFn">点一下</button><br /><br /><el-table v-load="loading" border :data="tableData" style="width: 80%"><el-table-column prop="name" label="姓名"></el-table-column><el-table-column prop="age" label="年龄"></el-table-column><el-table-column prop="home" label="家乡"></el-table-column><el-table-column prop="like" label="爱好"></el-table-column></el-table><br /><div class="box" v-load="loading">111</div><br /><div class="box" v-load="loading2">222</div></div>
</template><script>
export default {name: "myLoadName",data() {return {// 自定义指令方式,默认绑定的值是布尔值loading: true,// 如果想要有更多的配置项,就传一个对象,注意要指定字段loading2: {value: true,icon: "el-icon-eleme", // 自定义加载图标名text: "客官稍等哦...", // 自定义加载文字color: "red", // 自定义加载文字颜色bgColor: "#baf", // 自定义加载背景色},tableData: [{name: "孙悟空",age: 500,home: "花果山水帘洞",like: "桃子",},{name: "猪八戒",age: 88,home: "高老庄",like: "肉包子",},{name: "沙和尚",age: 1000,home: "通天河",like: "游泳",},],};},methods: {loadFn() {this.loading = !this.loading;this.loading2.value = !this.loading2.value;},},
};
</script><style lang='less' scoped>
.box {width: 160px;height: 80px;border: 2px solid #666;box-sizing: border-box;
}
</style>
本文转载于:
https://juejin.cn/post/7182375025368891429
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
记录--Vue自定义指令实现加载中效果v-load(不使用Vue.extend)相关推荐
- android圆形点击效果,Android 三种方式实现自定义圆形页面加载中效果的进度条
[实例简介] Android 三种方式实现自定义圆形页面加载中效果的进度条 [实例截图] [核心代码] ad376a86-a9aa-49bc-8cea-321bcff2c0c3 └── AnimRou ...
- vue自定义指令---处理加载图片失败时出现的碎图,onerror事件
目录 一.自定义指令 1.局部注册和使用 2.全局注册和使用 二.自定义指令处理图片加载失败(碎图) 一.自定义指令 vue中除v-model.v-show等内置指令之外,还允许注册自定义指令,获取D ...
- Android 三种方式实现自定义圆形页面加载中效果的进度条
转载:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=76872 一.通过动画实现 定义res/anim/loading.xml如 ...
- android dialog 自定义布局,Android自定义Dialog实现加载对话框效果
前言 最近开发中用到许多对话框,之前都是在外面的代码中创建AlertDialog并设置自定义布局实现常见的对话框,诸如更新提示等含有取消和删除两个按钮的对话框我们可以通过代码创建一个AlertDial ...
- JQuery datatables 给表格添加加载中效果
JQuery datatables 中如果有很多数据的话,加载就会很慢,这时候就需要使用加载中的效果,而datatables是提供了加载中的属性的:processing,加载中的style样式也是 可 ...
- 图片懒加载及Vue自定义图片懒加载指令
文章目录 监听滚动的方式 IntersectionObserver方式 自定义图片懒加载vue指令1 自定义图片懒加载vue指令2 lazyLoadImage.js main.js中注册指令 组件中使 ...
- layui -- loading实现加载中效果
1.layer.msg layer.msg('Loading...', {icon: 16, shade: 0.01, time: 5000 }); 2.弹出遮罩层显示加载中 var loading ...
- js 添加遮罩层(加载中效果)
1. 添加遮罩层 this.mask = document.createElement('div');this.mask.style.width = window.innerWidth + 'px'; ...
- vue自定义全局loading加载组件
1.实现效果 2.实现原理 Vue.extend:extend 创建的是 Vue 构造器,可通过 new Profile().$mount('#mount-point') 来挂载到指定的元素上. vu ...
最新文章
- Spring Boot轻松理解动态注入,删除bean
- MySQL导入导出数据和结构
- 在看不见的地方,AI正在7×24为你在线服务
- FrostSulliven最新发布引领全球增长的60大技术
- numpy逻辑运算符
- MFC线程优先级程序图示
- linux系统基础调优32条技巧
- pid算法通俗解释,平衡车,倒立摆,适合不理解PID算法的人来看!
- [系统安全] 四十四.APT系列(9)Metasploit技术之基础用法万字详解及防御机理
- 硬盘快速格式化和格式化的区别
- Leetcode--33. 搜索旋转排序数组
- Java消息服务~开发者分配的消息头
- GCC 放弃将代码贡献版权强制转让给 FSF!
- Asp.Net细节性问题精萃
- 常见的三种Content-Type
- win10-ubuntu-软件配置-开机root无密码-风扇转速调节
- java gbk 内码_JAVA 中文转GBK内码方法
- python blp模型 估计_简述BLP模型
- ArcGIS修改默认文件地理数据库
- mobi怎么在Android手机上打开?