您好,登錄后才能下訂單哦!
Vue是可以自定義指令的,最近學習過程中遇見了一個需要圖片懶加載的功能,最后參考了別人的代碼和思路自己重新寫了一遍。以下將詳細介紹如何實現自定義指令v-lazyload。
先看如何使用這個指令:
<img v-lazyload="p_w_picpathSrc" >
p_w_picpathSrc是要加載的圖片的實際路徑。
為了實現這個指令,我們首先單獨建立一個文件,名字為lazyload.js.并填寫基本的代碼,如下:
export (Vue , options = {})=> init =: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png' //例如:<img v-lazyload="p_w_picpathSrc" > ele是img binding是p_w_picpathSrc
'lazyload'
inserted 和 updated為Vue指令的執行不同階段提供的鉤子函數,查看Vue的官網可以看到一共有5個階段,
指令定義函數提供了幾個鉤子函數(可選):
bind
: 只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數可以定義一個在綁定時執行一次的初始化動作。
inserted
: 被綁定元素插入父節點時調用(父節點存在即可調用,不必存在于 document 中)。
update
: 被綁定元素所在的模板更新時調用,而不論綁定值是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新(詳細的鉤子函數參數見下)。
componentUpdated
: 被綁定元素所在模板完成一次更新周期時調用。
unbind
: 只調用一次, 指令與元素解綁時調用。
這里我們只用inserted和updated就夠了。
接下來我們具體實現addListener的實現。我們的具體思路如下:
1、先看看這個圖片是否需要懶加載。有兩種情況是不需要加載的,一是圖片還沒到達可視區域,二是圖片已經加載過了。
2、然后監聽窗口的scroll事件,判斷哪些圖片可以進行加載了。
這里我們需要一個需要進行監聽需要懶加載的圖片列表和一個需要記錄已經加載過得圖片列表。另外為了方便數組的操作,我們加一個數組的remove方法。
繼續我們的代碼。
export (Vue , options = {})=>
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 } } }
init =: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png' listenList = p_w_picpathCatcheList == (p_w_picpathSrc) => const isCanShow = (item) =>= () => const addListener = (ele,binding) => p_w_picpathSrc = = item = ele.src = init. 'lazyload'
接下來就幾個空方法的實現了。
isAlredyLoad ,判斷是否已經加載過了這個圖片
const isAlredyLoad = (p_w_picpathSrc) => { if(p_w_picpathCatcheList.indexOf(p_w_picpathSrc) > -1){ return true; }else{ return false; } }
isCanShow 圖片是否進入可視區域,如果已經進入則進行加載
//檢測圖片是否可以加載,如果可以則進行加載 const isCanShow = (item) =>{ var ele = item.ele; var src = item.src; //圖片距離頁面頂部的距離 var top = ele.getBoundingClientRect().top; //頁面可視區域的高度 var windowHeight = window.innerHight; //top + 10 已經進入了可視區域10像素 if(top + 10 < window.innerHeight){ var p_w_picpath = new Image(); p_w_picpath.src = src; p_w_picpath.onload = function(){ ele.src = src; p_w_picpathCatcheList.push(src); listenList.remove(item); } return true; }else{ return false; } };
onListenScroll監聽滾動事件,并且檢測是否進入可視區域。
const onListenScroll = () =>{ window.addEventListener('scroll',function(){ var length = listenList.length; for(let i = 0;i<length;i++ ){ isCanShow(listenList[i]); } }) }
最終我們的代碼如下:
//Vue 圖片懶加載export default (Vue , options = {})=>{ 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 = { lazyLoad: false, default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png' } var listenList = []; var p_w_picpathCatcheList = []; const isAlredyLoad = (p_w_picpathSrc) => { if(p_w_picpathCatcheList.indexOf(p_w_picpathSrc) > -1){ return true; }else{ return false; } } //檢測圖片是否可以加載,如果可以則進行加載 const isCanShow = (item) =>{ var ele = item.ele; var src = item.src; //圖片距離頁面頂部的距離 var top = ele.getBoundingClientRect().top; //頁面可視區域的高度 var windowHeight = window.innerHight; //top + 10 已經進入了可視區域10像素 if(top + 10 < window.innerHeight){ var p_w_picpath = new Image(); p_w_picpath.src = src; p_w_picpath.onload = function(){ ele.src = src; p_w_picpathCatcheList.push(src); listenList.remove(item); } return true; }else{ return false; } }; const onListenScroll = () =>{ window.addEventListener('scroll',function(){ var length = listenList.length; for(let i = 0;i<length;i++ ){ isCanShow(listenList[i]); } }) } //Vue 指令最終的方法 const addListener = (ele,binding) =>{ //綁定的圖片地址 var p_w_picpathSrc = binding.value; //如果已經加載過,則無需重新加載,直接將src賦值 if(isAlredyLoad(p_w_picpathSrc)){ ele.src = p_w_picpathSrc; return false; } var item = { ele:ele, src:p_w_picpathSrc } //圖片顯示默認的圖片 ele.src = init.default; //再看看是否可以顯示此圖片 if(isCanShow(item)){ return } //否則將圖片地址和元素均放入監聽的lisenList里 listenList.push(item); //然后開始監聽頁面scroll事件 onListenScroll(); } Vue.directive('lazyload',{ inserted:addListener, updated:addListener }) }
使用時需要在主文件中引入這個文件,并且vue.use();
import LazyLoad from 'lazyLoad.js' Vue.use(LazyLoad);
并且在需要懶加載的圖片上均按照如下使用v-lazyload指令即可
<img v-lazyload="p_w_picpathSrc" >
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。