项目中设备详情页中需要展示很多张图片,应用了图片懒加载,页面加载依旧超过3秒,最终决定,自己改写组件。
实现思路:页面首先加载三张图片,点击上一张下一张是依次加入一张图片
1、组件调用
<imgList :urls="urls" :order="order"></imgList>
其中urls是图片数据列表,order是图片展示类型(asce、desc),进入页面图片展示第一张还是最后一张
2、组件实现
<el-carousel ref="carousel"
trigger="click"
:initial-index="nowIndex"
height="500px"
:autoplay="false"
arrow="never">
<el-carousel-item v-for="(item, index) in urlShow" :key="index" width="100%" height="100%">
<el-image :src="item.srcPath" v-if="item" width="100%" height="100%"></el-image>
<smlCanvas
:coords="item.coors"
:src="item.srcPath"
v-if="item"
></smlCanvas>
</el-carousel-item>
<div @click="prevEvent" class="click-btn prev-btn"><i class="el-icon-caret-left"></i></div>
<div @click="nextEvent" class="click-btn next-btn"><i class="el-icon-caret-right"></i></div>
</el-carousel>
这里用了elementUI中的Carousel+Image,因为项目的需要,每张大图中都会将大图中某一区域放大展示,所以这里也用到了Canvas,这里就不介绍smlCanvas这个组件了。
3、实现细节
props: {
urls: Array,
order: String
},
调用组件是传过来的值
data () {
return {
urlShow: [], //展示图片列表
nowIndex: 0, //当前展示的幻灯片索引
urlsLen: 0, //urls的长度
showLen: 3, //此时页面中已加载多少张图片,初始值与initLen一致
initLen: 3, //页面进入加载图片的张数
prevNum: 0, //记录已点击上一张按钮多少次
nextNum: 0 //记录已点击下一张按钮多少次
}
},
showImg () {
this.urlsLen = this.urls.length
if (this.urlsLen < 3) { //当数据少于3张的时候
this.initLen = this.urlsLen
this.showLen = this.urlsLen
}
this.urlShow = new Array(this.urlsLen) //根据url的长度来创建一个展示图片的List
if (this.order === 'asce') { //进入页面展示第一张
this.nowIndex = 0
for (let i = 0; i < this.showLen; i++) { //赋值urlShow的前三个元素
this.urlShow[i] = this.urls[i]
}
} else { //进入页面展示最后一张
this.nowIndex = this.urlsLen - 1
for (let i = 0; i < this.showLen; i++) { //赋值urlShow的后三个元素
let num = this.urlsLen - 1 - i
this.urlShow[num] = this.urls[num]
}
}
},
created () {
this.showImg()
} // 初始化图片加载
prevEvent () { //上一张按钮点击
if (this.showLen < this.urlsLen) { //若图片还未加载完全
// 依次加入图片
if (this.order === 'asce') { //初始图片从一张展示,所以此时从队尾依次往前加载
let diff = this.urlsLen - this.prevNum - 1
if (!this.urlShow[diff]) { // 若数据不存在,赋值,存在就不需要了
this.urlShow[diff] = this.urls[diff]
}
} else { // 初始图片从最后一张展示,所以从第(urlsLen-initLen)张依次往前加载
let diff = this.urlsLen - this.initLen - this.prevNum - 1
if (!this.urlShow[diff]) {
this.urlShow[diff] = this.urls[diff]
}
}
this.prevNum += 1 //上一张点击次数+1
this.showLen += 1 //已加载的数据+1
}
if (this.nowIndex === 0) { //若此时展示的是第一张,上一张就是最后一张
this.nowIndex = this.urlsLen - 1
} else { //否则就是上一张
this.nowIndex = this.nowIndex - 1
}
this.$refs.carousel.setActiveItem(this.nowIndex)},
nextEvent () { //点击下一张按钮
if (this.showLen < this.urlsLen) {
if (this.order === 'asce') {
let diffNext = this.initLen + this.nextNum
if (!this.urlShow[diffNext]) {
this.urlShow[diffNext] = this.urls[diffNext]
}
} else {
let diffNext = this.nextNum
if (!this.urlShow[diffNext]) {
this.urlShow[diffNext] = this.urls[diffNext]
}
}
this.nextNum += 1
this.showLen += 1
}
if (this.nowIndex === this.urlsLen - 1) {
this.nowIndex = 0
} else {
this.nowIndex = this.nowIndex + 1
}
this.$refs.carousel.setActiveItem(this.nowIndex)
}
注意:如果不加入v-if="item"的话会报错,因为一开始urlShow中只有几个元素,其他的元素为空,找不到这些属性