赞
踩
上期实现了图片懒加载,但是经过测试,使用组件的方式会有卡顿的问题。通过查看图片请求,发现图片加载按顺序请求,如下图:
发现卡顿是因为图片从上到下依次加载,上面加载完成显示下面的,在滚动的时候就会感觉有卡顿感、
将上期组件内的 img 标签干掉,监听其父元素,当父元素进入可视区域内,动态创建 img 添加到父元素内,上代码,BGM 起
- <template>
- <div class="img-box" v-lazy="vm" :data-src="src">
- <!-- <img
- v-lazy="lazy"
- :data-src="src"
- src=""
- @load="loadImg"
- @error="error"
- alt=""
- /> -->
- <slot v-if="slotShow"></slot>
- <slot name="err" v-if="errFlag"></slot>
- </div>
- </template>
- <script>
- export default {
- props: {
- src: {
- type: String,
- default: "",
- },
- },
- data() {
- return {
- slotShow: true,
- errFlag: false,
- vm: null,
- };
- },
- created() {
- this.vm = this;
- },
-
- // 这个指令可以放到全局
- directives: {
- lazy: {
- inserted(el, { value }) {
- const imgSrc = el.dataset.src;
- const observer = new IntersectionObserver(([{ isIntersecting }]) => {
- if (isIntersecting) {
- // 动态创建 img 标签
- let img = document.createElement("img");
- img.src = imgSrc;
- img.style.width = "100%";
- img.style.height = "100%";
- // 添加图片加载完成事件,加载完成,让加载前的样式隐藏
- img.onload = function () {
- value.slotShow = false;
- };
- (img.onerror = function () {
- // 加载失败得时候 失败后得样式显示
- value.errFlag = true;
- // 让加载前得样式隐藏,
- value.slotShow = false;
- }),
- el.appendChild(img);
- observer.unobserve(el);
- }
- });
- observer.observe(el);
- },
- },
- },
- methods: {
- },
- };
- </script>
- <style lang="less" scoped>
- .img-box {
- display: flex;
- position: relative;
- overflow: hidden;
- }
- img {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- </style>
在父组件中使用
- <template>
- <div>
- <!-- 图片懒加载最好设置图片高度,因为不管你是监听滚动条的方式,还是利用监听器api实现,都跟元素可视区域有关系,而高度就影响是否在可视区域内 -->
- <lazyImg :index="i" v-for="(item,i) in lazyImgs" :key="i" :src="item">
- <!-- 图片加载之前默认在图片元素上方展示的样式--自由发挥 -->
- <div class="slot-txt">加载中</div>
- <template #err>
- <!-- 图片加载失败后在上面展示的样式--- 自由发挥 -->
- <div class="slot-txt"><img src="@/assets/images/icon_activity_copy_link.png" alt=""></div>
- </template>
- </lazyImg>
- </div>
- </template>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。