MST

星途 面试题库

面试题:Vue中如何使用指令实现懒加载的渐进式加载功能

在Vue项目中,已知有一个图片列表需要实现懒加载的渐进式加载功能。请描述实现思路,并给出关键代码示例,比如如何自定义一个Vue指令来处理图片的渐进式加载,从图片占位、逐步加载到显示完整图片的过程。
41.4万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 图片占位:在图片未加载时,使用一个占位元素(如一个小的灰色矩形或者特定的占位图片)来占据图片的位置,保证页面布局稳定。
  2. 渐进式加载:使用低分辨率的图片作为初始加载内容,随着网络情况逐步加载更高分辨率的图片。
  3. 懒加载:只有当图片进入浏览器的可视区域时,才开始加载图片,减少不必要的网络请求。

自定义Vue指令处理图片渐进式加载

  1. 创建Vue指令: 在Vue项目中,可以通过Vue.directive方法来创建自定义指令。
// 在main.js或者单独的directive文件中
Vue.directive('lazyProgressive', {
  inserted: function (el, binding) {
    const placeholder = 'placeholder.jpg'; // 占位图片路径
    const lowRes = 'lowRes.jpg'; // 低分辨率图片路径
    const highRes = binding.value; // 高分辨率图片路径
    el.innerHTML = `<img src="${placeholder}" alt="loading" class="placeholder">`;
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = new Image();
          img.src = lowRes;
          img.onload = () => {
            el.innerHTML = `<img src="${lowRes}" alt="loading" class="low-res">`;
            const highResImg = new Image();
            highResImg.src = highRes;
            highResImg.onload = () => {
              el.innerHTML = `<img src="${highRes}" alt="loaded" class="high-res">`;
            };
            highResImg.onerror = () => {
              console.error('高分辨率图片加载失败');
            };
          };
          img.onerror = () => {
            console.error('低分辨率图片加载失败');
          };
          observer.unobserve(el);
        }
      });
    });
    observer.observe(el);
  }
});
  1. 在模板中使用指令: 假设在组件模板中有一个图片列表:
<template>
  <div>
    <div v-for="(img, index) in imgList" :key="index" v-lazyProgressive="img.highResUrl">
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      imgList: [
        { highResUrl: 'highRes1.jpg' },
        { highResUrl: 'highRes2.jpg' }
      ]
    };
  }
};
</script>

<style scoped>
.placeholder {
  width: 100%;
  height: 100%;
  background-color: lightgray;
}
.low-res,
.high-res {
  width: 100%;
  height: 100%;
}
</style>

上述代码首先使用占位图片作为初始显示,当图片进入视口时,先加载低分辨率图片,低分辨率图片加载成功后再加载高分辨率图片,并替换显示。