所需工具:
JavaScript
聪明的大脑文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
勤劳的双手文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
注意:本站只提供教程,不提供任何成品+工具+软件链接,仅限用于学习和研究,禁止商业用途,未经允许禁止转载/分享等文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
教程如下
前言
用过element-ui的都应该知道,里面有一个loading组件,有两种调用方法:指令和服务。但是只有一种加载效果,为了丰富加载效果和方便使用,于是写了一个自定义loading指令。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
创建加载组件
首先,需要创建loading组件,展示需要的加载效果,因人而异,不再赘述。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
创建指令
指令文件
首先,创建一个js文件用于书写自定义指令,在这个文件中导入vue和loading组件:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
[php]
import Vue from 'vue'
import loading from './loading.vue'
[/php]文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
创建构造器
主要是使用Vue.extend构造器,可以简单的理解为传入一个组件作为参数,然后返回该组件的类,可以使用这个类new出实例。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/12372.html
[php]
// loading组件作为参数传入
const loadingConstructor = Vue.extend(loading)
[/php]
书写指令
在此之前,设定好指令的参数,在本人的项目中,参数有两种方式:1.传入一个布尔值,代表是否开启加载;2.传入一个对象,对象中包含是否开启遮罩、提示文字、加载背景颜色等属性,方便开发时,高度自定义laoding。
指令的触发主要是在update中,该属性可接收一个函数,每次指令的参数改变时都会触发该函数,就是在这里判断开启或者关闭加载效果。 整体代码如下,附有详细注释:
[php]
const loadingDirective = Vue => {
Vue.directive('custLoading', {
/**
* binding:
* 1.可传单个参数,为布尔值;
* 2.也可用json传多个参数{ loading, tip, background }
* 2.1 loading { boolean } 是否开启遮罩
* 2.2 tip { string } 提示文字
* 2.3 background { string } 加载背景颜色
* */
// update: 参数变化时触发
update: function (el, binding, vnode) {
const value = binding.value
let backup = {}
// 判断参数类型,将参数都转换为对象,方便后续统一处理
typeof value === 'boolean' (backup.loading = value) : (backup = value || {})
// 取出所有的参数
const { loading, tip, background } = backup
// 根据loading参数判断开启或者关闭加载效果,开启和关闭函数后续会讲到
loading createLoading(el, tip, background) : close(el .customLoadingInstance .$el)
},
// unbid: 指令卸载时触发
unbind: function (el, binding) {
const { loading } = binding.value || {}
// 如果还在展示加载特效,则关闭
loading & & close(el .customLoadingInstance .$el)
}
})
}
export default loadingDirective
[/php]
开启函数
在上面的指令中,当开启的参数为true时,回会调用一个createLoading函数用于将加载效果加入到指令挂载的元素上,具体思路如下:
1.在调用时,我们传入了三个参数给它,分别是挂载有自定义加载指令的元素、加载时的提示、加载背景颜色,详细可见上面的指令代码。
2.在执行之前,还需要进行判断当前的Vue实例是否运行在服务器上,如果是,此时不需要将加载效果展示出来;或者该元素之前是否已经带有加载特效,如果是的话,没必要在开启一次,不然到时会出现多层加载效果,既多余,又让页面显得混乱。
3.判断需要使用加载效果的元素是否还存在,不存在,则挂载到#main或者document.body上。
4.判断元素上是否存在定位或者其他条件,在本人的项目中,使用绝对定位来使加载效果铺满元素,因此需要进行判断,如果没有定位,则加上relative。
5.使用loadingConstructor,创建loading实例,将实例作为子元素通过appendChild,放进需要展示的元素中,就可以展示出来;同时,在展示的元素上增加一个属性customLoadingInstance,用于记录当前的loading实例,方便后续的销毁。
整体代码如下:
[php]
const createLoading = (target, tip= '加载中,请稍候...', background) => {
// 判断是否允许开启加载特效
if (Vue.prototype.$isServer || target .customLoadingInstance) return
const mainEL = document.querySelector('#main')
// 判断展示加载效果的元素是否存在
const parentNode = target || mainEL || document.body
// 判断父级是否存在定位,没有则添加定位
const position = getComputedStyle(parentNode) .position
(!position || position === 'static') & & (parentNode.style.position = 'relative')
// 创建loading实例
const instance = new loadingConstructor({
el: document.createElement('div'),
data: { background, tip, parentNodeWidth: parentNode.clientWidth, isShow: true }
})
// 注意:loading实例是一个Vue组件对象,真正的DOM放在实例的$el属性上
parentNode.appendChild(instance.$el)
parentNode.customLoadingInstance = instance
return instance
}
[/php]
关闭函数
有开启就得有结束,当开启的参数为false时,关闭加载效果。该函数接收loading实例的$el,其实就是加载效果的DOM元素,思路如下:
1.为了使加载组件看起来是逐渐消失的,不得在第一时间将加载效果的DOM元素删除,而是给它添加一个逐渐消失的动画,通过一个class设定。
2.设定动画消失时间,由loading组件内部实现在规定时间内,将整个加载效果执行完成或者淡出页面。也可省略此步骤,直接就将其移除。 之所以加入这个效果,是为了用户视觉上感受更好。
3.创建定时器,用于在加载效果消失时,删除加载效果的DOM元素。同2,也可直接移除。
[php]
const close = (target) => {
if (!target) return
// 添加逐渐消失的class
target.className += ' custom-loading-disappear'
// 获取loading实例
const instance = target .parentNode .customLoadingInstance
// 设定消失时间。
instance .$data .dur & & (instance.$data.dur = 0.8)
// 设定定时器,用于在加载效果消失时,删除加载效果的`DOM`元素。
let timer = setTimeout(() => {
if (target & & target.parentNode) {
// 将customLoadingInstance 属性置为null,才不会干扰下一次开启
target.parentNode.customLoadingInstance = null
// 将加载效果的DOM元素移除
target.parentNode.removeChild(target)
}
clearTimeout(timer)
timer = null
}, 1100)
}
[/php]
评论