亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

實現一個Vue自定義指令懶加載的實例代碼

發布時間:2020-07-18 17:30:36 來源:億速云 閱讀:197 作者:小豬 欄目:web開發

這篇文章主要講解了實現一個Vue自定義指令懶加載的實例代碼,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。

在項目中如果有大量的圖片需要加載的時候,就可以考慮使用懶加載了,懶加載其實就是監聽瀏覽器的滾動,當滾動到一定的范圍的時候就將圖片的真實路徑賦給src,然后取消監聽。實現的方法也比較簡單,可以通過懶加載的插件實現,也可以手寫,手寫通過vue自定義指令來實現,一般情況自定義指令用的也不多,比較vue自帶的就夠用了,大型復雜的項目的可能用的多。

什么是圖片懶加載

當我們向下滾動的時候圖片資源才被請求到,這也就是我們本次要實現的效果,進入頁面的時候,只請求可視區域的圖片資源這也就是懶加載。

比如我們加載一個頁面,這個頁面很長很長,長到我們的瀏覽器可視區域裝不下,那么懶加載就是優先加載可視區域的內容,其他部分等進入了可視區域在加載。

這個功能非常常見,你打開淘寶的首頁,向下滾動,就會看到會有圖片不斷的加載;你在百度中搜索圖片,結果肯定成千上萬條,不可能所有的都一下子加載出來的,很重要的原因就是會有性能問題。你可以在Network中查看,在頁面滾動的時候,會看到圖片一張張加載出來。

實現一個Vue自定義指令懶加載的實例代碼

為什么要做圖片懶加載

懶加載是一種網頁性能優化的方式,它能極大的提升用戶體驗。就比如說圖片,圖片一直是影響網頁性能的主要元兇,現在一張圖片超過幾兆已經是很經常的事了。如果每次進入頁面就請求所有的圖片資源,那么可能等圖片加載出來用戶也早就走了。所以,我們需要懶加載,進入頁面的時候,只請求可視區域的圖片資源。

總結出來就兩個點:

1.全部加載的話會影響用戶體驗

2.浪費用戶的流量,有些用戶并不像全部看完,全部加載會耗費大量流量。

懶加載原理

圖片的標簽是 img標簽,圖片的來源主要是 src屬性,瀏覽器是否發起加載圖片的請求是根據是否有src屬性決定的。

所以可以從 img標簽的 src屬性入手,在沒進到可視區域的時候,就先不給 img 標簽的 src屬性賦值。

懶加載實現

實現效果圖:

實現一個Vue自定義指令懶加載的實例代碼

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 <style>
  div {
   display: flex;
   flex-direction: column;
  }
  img {
   width: 100%;
   height: 300px;
  }
 </style>
</head>
<body>
 <div>
  <img data-src="https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657907683.jpeg">
  <img data-src="https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657913523.jpeg">
  <img data-src="https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657925550.jpeg">
  <img data-src="https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657930289.jpeg">
  <img data-src="https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657934750.jpeg">
  <img data-src="https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657918315.jpeg">
 </div>
</body>
</html>

監聽滾動根據offsetTop判斷

const imgs = [...document.getElementsByTagName('img')];
 let n = 0;

 lazyload();
 function throttle(fn, wait) {
 let timer = null;
 return function(...args) {
  if(!timer) {
   timer = setTimeout(() => {
    timer = null;
    fn.apply(this, args)
   }, wait)
  }
 }
 }
 window.addEventListener('scroll', throttle(lazyload, 200));
 
 function lazyload() {
 var innerHeight = window.innerHeight; 
 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 for(let i = n; i < imgs.length; i++) {
  if(imgs[i].offsetTop < innerHeight + scrollTop) {
   imgs[i].src = imgs[i].getAttribute("data-src");
   n = i + 1;
  }
  
 }
 }

可能會存在下面幾個問題:

  • 每次滑動都要執行一次循環,如果有1000多個圖片,性能會很差
  • 每次讀取 scrollTop 都會引起回流
  • scrollTop跟DOM的嵌套關系有關,應該根據getboundingclientrect獲取
  • 滑到最后的時候刷新,會看到所有的圖片都加載了

IntersectionObserver

const imgs = [...document.getElementsByTagName('img')];
// 當監聽的元素進入可視范圍內的會觸發回調
 if(IntersectionObserver) {
  let lazyImageObserver = new IntersectionObserver((entries, observer) => {
   entries.forEach((entry, index) => {
    let lazyImage = entry.target;
    // 相交率,默認是相對于瀏覽器視窗
    if(entry.intersectionRatio > 0) {
    lazyImage.src = lazyImage.getAttribute('data-src');
    // 當前圖片加載完之后需要去掉監聽
     lazyImageObserver.unobserve(lazyImage);
    }

   })
  })
  for(let i = 0; i < imgs.length; i++) {
  lazyImageObserver.observe(imgs[i]);
  }
 }

codePen

vue自定義指令-懶加載

Vue自定義指令

下面的api來自官網自定義指令:

鉤子函數

  • bind: 只調用一次,指令第一次綁定到元素時調用。在這里可以進行一次性的初始化設置。
  • inserted: 被綁定元素插入父節點時調用 (僅保證父節點存在,但不一定已被插入文檔中)。
  • update: 所在組件的 VNode 更新時調用,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新
  • componentUpdated: 指令所在組件的 VNode 及其子 VNode 全部更新后調用。
  • unbind: 只調用一次,指令與元素解綁時調用。

鉤子函數參數

指令鉤子函數會被傳入以下參數:

  • el:指令所綁定的元素,可以用來直接操作 DOM。
  • binding:一個對象,包含以下 property:
    • name:指令名,不包括 v- 前綴。
    • value:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值為 2。
    • oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
    • expression:字符串形式的指令表達式。例如 v-my-directive="1 + 1" 中,表達式為 "1 + 1"。
    • arg:傳給指令的參數,可選。例如 v-my-directive:foo 中,參數為 "foo"。
    • modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象為 { foo: true, bar: true }。
  • vnode:Vue 編譯生成的虛擬節點。
  • oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。

實現 v-lazyload 指令

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
   img {
    width: 100%;
    height: 300px;
   }
  </style>
 </head>
 <body>
  <div id="app">
   <p v-for="item in imgs" :key="item">
    <img v-lazyload="item">
   </p>
  </div>
 </body>
 <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 <script>
  Vue.directive("lazyload", {
   // 指令的定義
   bind: function(el, binding) {
    let lazyImageObserver = new IntersectionObserver((entries, observer) => {
     entries.forEach((entry, index) => {
      let lazyImage = entry.target;
      // 相交率,默認是相對于瀏覽器視窗
      if(entry.intersectionRatio > 0) {
       lazyImage.src = binding.value;
       // 當前圖片加載完之后需要去掉監聽
       lazyImageObserver.unobserve(lazyImage);
      }

     })
    })
    lazyImageObserver.observe(el);
   },
  });
  var app = new Vue({
   el: "#app",
   data: {
    imgs: [
     'https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657907683.jpeg',
     'https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657913523.jpeg',
     'https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657925550.jpeg',
     'https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657930289.jpeg',
     'https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657934750.jpeg',
     'https://cdn.suisuijiang.com/ImageMessage/5adad39555703565e79040fa_1590657918315.jpeg',
    ]
   },
  });
 </script>
</html>

看完上述內容,是不是對實現一個Vue自定義指令懶加載的實例代碼有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤凰县| 鄂托克旗| 安阳县| 什邡市| 青神县| 津市市| 宜城市| 湖北省| 抚松县| 金门县| 西乡县| 高安市| 鄂托克旗| 芦溪县| 开原市| 拜泉县| 阳朔县| 岑巩县| 松原市| 绥棱县| 平乐县| 郧西县| 台南县| 赫章县| 四川省| 宝坻区| 山阴县| 绍兴县| 沾化县| 沂水县| 金门县| 柘城县| 绍兴县| 科技| 柏乡县| 康定县| 永州市| 杭锦后旗| 泰安市| 屏山县| 三原县|