uniapp swiper实现图片预览 预览一张图片加载前后两张 实现性能优化

背景:

使用uniapp框架在做h5项目时,领导要求预览图片时不能一次性加载完所有的图片,需要看一张加载一张,这样用户不费流量,优化h5的性能。
首先uniapp官网实现图片预览使用的是uni.preview api,但是这样传的urls数组,在点击图片进行预览时一次性加载了所有的图片。
所以要实现图片预览,点击一张加载这张图片需要自已写预览组件。
这里用到的是swiper组件来进行预览功能。

1、新建公共组件 previewImage.vue

<template>
	<view class="previewImg" v-if="show" @touchmove.stop.prevent :class="{
     
     'pc-full':!$util.isMobile(),'full':$util.isMobile()}">
		<view class="mask" @click="close" :class="{
     
     'pc-full':!$util.isMobile(),'full':$util.isMobile()}">
			<swiper class="mask-swiper" :current="index" @change="swiperChange" :disable-touch="false" :class="{
     
     'pc-full':!$util.isMobile(),'full':$util.isMobile()}">
				<swiper-item v-for="(img, i) in pageList" :key="i">
					<image class="mask-swiper-img" :src="img" mode="aspectFit" :class="{
     
     'pc-full':!$util.isMobile(),'full':$util.isMobile()}"/>
				</swiper-item>
			</swiper>
		</view>
		<view class="page" v-if="imgs.length > 0">
			{
   
   { index + 1 }} / {
   
   { imgs.length }}
		</view>
		<view class="close-btn" @click.stop="close()">
			<icon type="clear" size="30" />
		</view>
	</view>
</template>
<script>
export default {
    
    
    name: 'previewImage',
    props: {
    
    
    // 图片数组,由父组件传值
        imgs: {
    
    
            type: Array,
            default: () => {
    
    
                return [];
            }
        },
    },
    data() {
    
    
        return {
    
    
            show: false, // 展示预览组件
            index: 0,
            pageList: [],
        };
    },
    methods: {
    
    
        swiperChange(e) {
    
    
            let
                oldPageIndex = this.index, // 之前展示的页面索引
                newPageIndex = e.detail.current; // 滑动后新展示的页面索引
            // 判断是否由用户触摸引起的
            if (e.detail.source == 'touch') {
    
    
                // 判断滑动方向
                if (oldPageIndex < newPageIndex) {
    
    
               		// 向左滑
                    // 判断是否到最后一张,并且地址信息是否为空
                    if (newPageIndex < this.imgs.length - 1 && !this.pageList[newPageIndex + 1]) {
    
    
                        this.pageList[newPageIndex + 1] = this.imgs[newPageIndex + 1];
                    }
                    this.index = newPageIndex;
                } else if (oldPageIndex > newPageIndex) {
    
    
                	// 向右滑
                	// 判断是否到第一张
                    if (newPageIndex < this.imgs.length - 1 && !this.pageList[newPageIndex - 1]) {
    
    
					    this.pageList[newPageIndex - 1] = this.imgs[newPageIndex - 1];
                    }
                    this.index = newPageIndex;
                }
            }
        },
        open(e) {
    
    
            const _this = this;
            _this.index = e;
            _this.show = true;
            // 根据图片总数,创建需要渲染的空数组
            let pageList = new Array(_this.imgs.length).fill('');
            // 初始化渲染数组,载入当前图片,并且预载入下一张图片
            // 如果当前不是在第一张,预载入当前图片+下一张图片+上一张图片
            // 如果当前是第一张,预载入下一张图片
            // 如果当前是最后一张,预载入上一张图片
            pageList[_this.index] = _this.imgs[_this.index];
            if(_this.index === 0 && _this.imgs.length > _this.index + 1){
    
    
                pageList[_this.index + 1] = _this.imgs[_this.index + 1];
            }else if(_this.index !== 0 && _this.index + 1 > 0 && _this.index + 1 < _this.imgs.length){
    
    
                pageList[_this.index + 1] = _this.imgs[_this.index + 1];
                pageList[_this.index - 1] = _this.imgs[_this.index - 1];
            }else if(_this.imgs.length = _this.index + 1){
    
    
                pageList[_this.index - 1] = _this.imgs[_this.index - 1];
            }
            // 渲染页面
            _this.pageList = pageList;
        },
        //关闭预览
        close() {
    
    
            this.show = false;
            this.index = 0;
        }
    }
};
</script>

2、调用预览组件

新建父组件index.vue

<view class="img-item" v-for="(img, imgIndex) in files" :key="imgIndex" @click.stop="previewImage(imgIndex)">
	<img :src="img.imgurl" />
</view>
<preview-image ref="previewImage" :imgs="imgs"></preview-image>
import previewImage from '@/components/previewImage.vue';
export default {
    
    
    components: {
    
    
        previewImage
    },
     data() {
    
    
        return {
    
    
        	files:[], // 循坏渲染到页面的图片
            imgs:[], // 进行预览的图片数组字符串
        }
    },
    methods:{
    
    
   // 预览事件,点击当前图片,将图片索引传给事件
	    previewImage(index){
    
    
			_this.$nextTick(function(){
    
    
				// 执行预览子组件的open事件
	            _this.$refs.previewImage.open(index);
	        });
		}	
	}
}

猜你喜欢

转载自blog.csdn.net/qiaoqiaohong/article/details/123270209