Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍。以下将详细介绍如何实现自定义指令v-lazyload。
先看如何使用这个指令:
imageSrc是要加载的图片的实际路径。
为了实现这个指令,我们首先单独建立一个文件,名字为lazyload.js.并填写基本的代码,如下:
inserted 和 updated为Vue指令的执行不同阶段提供的钩子函数,查看Vue的官网可以看到一共有5个阶段,
指令定义函数提供了几个
钩子函数
(可选):bind:
只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。inserted:
被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。update:
被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。componentUpdated:
被绑定元素所在模板完成一次更新周期时调用。这里我们只用inserted和updated就够了。
接下来我们具体实现addListener的实现。我们的具体思路如下:
1、先看看这个图片是否需要懒加载。有两种情况,一是图片还没到达可视区域,二是图片已经加载过了。
2、然后监听窗口的scroll事件,判断哪些图片可以进行懒加载了。
这里我们需要一个需要进行监听需要懒加载的图片列表和一个需要记录已经加载过得图片列表。另外为了方便数组的操作,我们加一个数组的remove方法。
继续我们的代码。
<div class="jb51code">
<pre class="brush:js;">
//Vue 图片懒加载
export default (Vue,options = {})=>{
//数组item remove方法
if(!Array.prototype.remove){
Array.prototype.remove = function(item){
if(!this.length) return
var index = this.indexOf(item);
if( index > -1){
this.splice(index,1);
return this
}
}
}
var init = {
default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'
}
//需要进行监听的图片列表,还没有加载过得
var listenList = [];
//已经加载过得图片缓存列表
var imageCatcheList = [];
//是否已经加载过了
const isAlredyLoad = (imageSrc) => {
}
//检测图片是否可以加载,如果可以则进行加载
const isCanShow = (item) =>{
};
//添加监听事件scroll
const onListenScroll = () =>{
}
//Vue 指令最终的方法
const addListener = (ele,binding) =>{
//绑定的图片地址
var imageSrc = binding.value;
//如果已经加载过,则无需重新加载,直接将src赋值
if(isAlredyLoad(imageSrc)){
ele.src = imageSrc;
return false;
}
var item = {
ele:ele,src:imageSrc
}
//图片显示默认的图片
ele.src = init.default;
//再看看是否可以显示此图片
if(isCanShow(item)){
return
}
//否则将图片地址和元素均放入监听的lisenList里
listenList.push(item);
//然后开始监听<a href="https://www.jb51.cc/tag/yemian/" target="_blank" class="keywords">页面</a>scroll事件
onListenScroll();
}
Vue.directive('lazyload',updated:addListener
})
}