aurora-article
aurora-article copied to clipboard
vue 实现图片不同加载方式
使用 vue 实现图片显示在视图时加载和图片按顺序加载两种方式,代码使用了 vue3 的新的组合式 api,代码较简单,可以稍微改进下。
首先是两种方式都要用到 CoverImage 组件
整个组件最重要的部分就是 loadImg 方法,这个方法用来加载图片,并当图片加载完成后显示该图片。
<template>
<div>
<img :src="imgSrc" v-show="visible" />
</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: `CoverImage`,
setup() {
const imgSrc = ref(``)
const visible = ref(false)
const loadImg = function (src) {
let img = new Image()
img.src = src
img.onload = img.onerror = () => {
imgSrc.value = src
visible.value = true
this.$emit(`addLoadIndex`)
}
}
return { imgSrc, visible, loadImg }
},
}
</script>
图片显示在视图时加载
主要是利用js提供的 IntersectionObserver 对象来实现。
<template>
<div>
<div class="img-wrap" v-for="(src, index) in srcList" :key="index">
<cover-image :ref="setItemRef" :eleIndex="index"></cover-image>
</div>
</div>
</template>
<script>
import { onBeforeUpdate, onMounted } from 'vue'
import CoverImage from './components/CoverImage'
export default {
name: `CoverShowList`,
components: {
CoverImage
},
setup() {
const srcList = [
`https://i.postimg.cc/prGHDHk6/14.jpg`,
`https://i.postimg.cc/tTzy4P6y/13.jpg`,
`https://i.postimg.cc/YqDrF1sC/10.jpg`
]
let itemRefs = []
let io = null
const setItemRef = function (el) {
itemRefs.push(el)
}
const getStatus = function (items) {
items.map((item) => {
if (!item.isIntersecting) return
const eleIndex = item.target.getAttribute(`eleIndex`)
itemRefs[eleIndex].loadImg(srcList[eleIndex])
io.unobserve(item.target)
})
}
onMounted(() => {
io = new IntersectionObserver(getStatus)
itemRefs.map((item) => {
io.observe(item.$el)
})
})
onBeforeUpdate(() => {
itemRefs = []
})
return { srcList, setItemRef }
}
}
</script>
<style>
.img-wrap {
border: 1px solid red;
padding: 400px 200px;
margin-top: 200px;
}
.display-none {
display: none;
}
</style>
图片按顺序加载
在父组件中设置一个 loadIndex 变量,然后用watch监听loadIndex的变化。
<template>
<div>
<div v-for="(item, i) in srcList" :key="i">
<cover-image :ref="setItemRef" @addLoadIndex="addLoadIndex"></cover-image>
</div>
</div>
</template>
<script>
import { ref, watch, onMounted, onBeforeUpdate } from 'vue'
import CoverImage from './components/CoverImage'
export default {
name: `CoverImageList`,
components: {
CoverImage
},
setup() {
const srcList = [
`https://i.postimg.cc/prGHDHk6/14.jpg`,
`https://i.postimg.cc/tTzy4P6y/13.jpg`,
`https://i.postimg.cc/YqDrF1sC/10.jpg`
]
let itemRefs = []
const loadIndex = ref(0)
const setItemRef = function (el) {
itemRefs.push(el)
}
const addLoadIndex = function () {
loadIndex.value++
}
onMounted(() => {
itemRefs[loadIndex.value].loadImg(srcList[loadIndex.value])
})
onBeforeUpdate(() => {
itemRefs = []
})
watch(loadIndex, (value) => {
itemRefs[value] && itemRefs[value].loadImg(srcList[loadIndex.value])
})
return { loadIndex, srcList, setItemRef, addLoadIndex }
}
}
</script>