vue实现图片组件
Vue 实现图片组件的方法
基础图片组件实现
创建一个基础的图片组件,接收图片路径作为 props,并显示图片。
<template>
<img :src="src" :alt="alt" :width="width" :height="height" />
</template>
<script>
export default {
props: {
src: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
}
}
}
</script>
添加懒加载功能
使用 Intersection Observer API 实现图片懒加载,提升页面性能。

<template>
<img
ref="image"
:src="placeholder"
:alt="alt"
:width="width"
:height="height"
@load="handleLoad"
/>
</template>
<script>
export default {
props: {
src: {
type: String,
required: true
},
placeholder: {
type: String,
default: 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
},
alt: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
}
},
mounted() {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.$refs.image.src = this.src
observer.unobserve(entry.target)
}
})
})
observer.observe(this.$refs.image)
},
methods: {
handleLoad() {
this.$emit('load')
}
}
}
</script>
添加图片加载状态处理
处理图片加载过程中的不同状态,如加载中、加载成功和加载失败。
<template>
<div class="image-container">
<img
v-if="status === 'loaded'"
:src="src"
:alt="alt"
:width="width"
:height="height"
/>
<div v-else-if="status === 'loading'" class="loading-placeholder">
<!-- 加载中占位内容 -->
</div>
<div v-else-if="status === 'error'" class="error-placeholder">
<!-- 加载失败占位内容 -->
</div>
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
}
},
data() {
return {
status: 'loading' // loading, loaded, error
}
},
mounted() {
const img = new Image()
img.src = this.src
img.onload = () => {
this.status = 'loaded'
}
img.onerror = () => {
this.status = 'error'
}
}
}
</script>
<style>
.image-container {
position: relative;
width: 100%;
height: 100%;
}
.loading-placeholder,
.error-placeholder {
width: 100%;
height: 100%;
background-color: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
}
</style>
实现图片预览功能
添加点击图片放大预览的功能。

<template>
<div>
<img
:src="src"
:alt="alt"
:width="width"
:height="height"
@click="showPreview"
style="cursor: pointer;"
/>
<div v-if="previewVisible" class="preview-modal" @click="hidePreview">
<img :src="src" :alt="alt" class="preview-image" />
</div>
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
}
},
data() {
return {
previewVisible: false
}
},
methods: {
showPreview() {
this.previewVisible = true
document.body.style.overflow = 'hidden'
},
hidePreview() {
this.previewVisible = false
document.body.style.overflow = ''
}
}
}
</script>
<style>
.preview-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
.preview-image {
max-width: 90%;
max-height: 90%;
object-fit: contain;
}
</style>
响应式图片组件
根据屏幕尺寸加载不同大小的图片,优化性能。
<template>
<picture>
<source
v-for="(source, index) in sources"
:key="index"
:media="source.media"
:srcset="source.srcset"
:type="source.type"
/>
<img
:src="fallback"
:alt="alt"
:width="width"
:height="height"
/>
</picture>
</template>
<script>
export default {
props: {
sources: {
type: Array,
required: true,
validator: value => value.every(item =>
item.media && item.srcset
)
},
fallback: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
}
}
}
</script>
使用方法:
<responsive-image
:sources="[
{ media: '(min-width: 1200px)', srcset: 'large.jpg' },
{ media: '(min-width: 768px)', srcset: 'medium.jpg' },
{ media: '(max-width: 767px)', srcset: 'small.jpg' }
]"
:fallback="'fallback.jpg'"
alt="Responsive image"
/>
这些方法提供了从基础到高级的图片组件实现方案,可以根据项目需求选择适合的方式或组合使用多种功能。






