圖片懶加載其實就是延遲加載。也就是不用一次性加載全部的圖片,等到用戶須要某張圖片的時候再加載,這樣能夠避免在同一時間請求大量的數據。也就是當圖片滾動到可視區域的時候再去加載圖片。javascript
Vue
中除了平時經常使用的v-show,v-bind
等指令外,還能夠自定義指令。因爲自定義指令過於簡單,這裏只是大體說一下用獲得的鉤子函數的做用。vue
bind
:只調用一次,指令綁定到元素時調用,能夠用來初始化。inserted
:被綁定的元素插入到父節點時調用。在component
文件夾中新建LazyLoad
文件夾,在文件夾裏新建index.js
。java
代碼以下:git
const LazyLoad = { // install方法 install(Vue,options){ // 代替圖片的loading圖 let defaultSrc = options.default; Vue.directive('lazy',{ bind(el,binding){ LazyLoad.init(el,binding.value,defaultSrc); }, inserted(el){ // 兼容處理 if('IntersectionObserver' in window){ LazyLoad.observe(el); }else{ LazyLoad.listenerScroll(el); } }, }) }, // 初始化 init(el,val,def){ // data-src 儲存真實src el.setAttribute('data-src',val); // 設置src爲loading圖 el.setAttribute('src',def); }, // 利用IntersectionObserver監聽el observe(el){ var io = new IntersectionObserver(entries => { let realSrc = el.dataset.src; if(entries[0].isIntersecting){ if(realSrc){ el.src = realSrc; el.removeAttribute('data-src'); } } }); io.observe(el); }, // 監聽scroll事件 listenerScroll(el){ let handler = LazyLoad.throttle(LazyLoad.load,300); LazyLoad.load(el); window.addEventListener('scroll',() => { handler(el); }); }, // 加載真實圖片 load(el){ let windowHeight = document.documentElement.clientHeight let elTop = el.getBoundingClientRect().top; let elBtm = el.getBoundingClientRect().bottom; let realSrc = el.dataset.src; if(elTop - windowHeight<0&&elBtm > 0){ if(realSrc){ el.src = realSrc; el.removeAttribute('data-src'); } } }, // 節流 throttle(fn,delay){ let timer; let prevTime; return function(...args){ let currTime = Date.now(); let context = this; if(!prevTime) prevTime = currTime; clearTimeout(timer); if(currTime - prevTime > delay){ prevTime = currTime; fn.apply(context,args); clearTimeout(timer); return; } timer = setTimeout(function(){ prevTime = Date.now(); timer = null; fn.apply(context,args); },delay); } } } export default LazyLoad;
在main.js
裏添加github
import LazyLoad from './components/LazyLoad'; Vue.use(LazyLoad,{ default:'https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyof9vr4mj3044032dfl.jpg' });
在組件中使用app
<img v-lazy="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfynwi1sejj30ij0nrdx0.jpg" />
https://github.com/erdong0604/demo/tree/master/vue-demo/v-lazy函數