vue实现图片组件
Vue 实现图片组件的方法
基础图片组件实现
创建一个基础的图片组件,支持动态传入图片路径和替代文本。在Vue项目中新建一个ImageComponent.vue文件:
<template>
<img :src="src" :alt="alt" :class="className" />
</template>
<script>
export default {
name: 'ImageComponent',
props: {
src: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
className: {
type: String,
default: ''
}
}
}
</script>
添加懒加载功能
使用Intersection Observer API实现图片懒加载,减少初始页面加载时间:

<template>
<img
ref="image"
:src="placeholder"
:alt="alt"
:class="className"
@load="handleLoad"
/>
</template>
<script>
export default {
name: 'LazyImage',
props: {
src: {
type: String,
required: true
},
placeholder: {
type: String,
default: 'data:image/png;base64,...'
},
alt: {
type: String,
default: ''
},
className: {
type: String,
default: ''
}
},
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('loaded')
}
}
}
</script>
实现图片加载状态处理
添加加载中和加载失败的状态处理,提升用户体验:

<template>
<div class="image-container">
<img
v-if="!isError"
:src="currentSrc"
:alt="alt"
:class="className"
@load="handleLoad"
@error="handleError"
/>
<div v-if="isLoading" class="loading-indicator">Loading...</div>
<div v-if="isError" class="error-message">Failed to load image</div>
</div>
</template>
<script>
export default {
name: 'SmartImage',
props: {
src: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
className: {
type: String,
default: ''
}
},
data() {
return {
currentSrc: this.src,
isLoading: true,
isError: false
}
},
methods: {
handleLoad() {
this.isLoading = false
this.$emit('loaded')
},
handleError() {
this.isLoading = false
this.isError = true
this.$emit('error')
}
}
}
</script>
<style scoped>
.image-container {
position: relative;
}
.loading-indicator,
.error-message {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
}
</style>
实现响应式图片组件
支持根据不同屏幕尺寸加载不同图片,优化性能:
<template>
<picture>
<source
v-for="(source, index) in sources"
:key="index"
:media="source.media"
:srcset="source.srcset"
/>
<img
:src="fallback"
:alt="alt"
:class="className"
/>
</picture>
</template>
<script>
export default {
name: 'ResponsiveImage',
props: {
sources: {
type: Array,
required: true,
validator: value => value.every(item => 'media' in item && 'srcset' in item)
},
fallback: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
className: {
type: String,
default: ''
}
}
}
</script>
图片组件使用示例
在父组件中使用上述图片组件:
<template>
<div>
<ImageComponent
src="/path/to/image.jpg"
alt="Description"
class="custom-image"
/>
<LazyImage
src="/path/to/large-image.jpg"
placeholder="/path/to/placeholder.jpg"
alt="Lazy loaded"
@loaded="handleImageLoaded"
/>
<SmartImage
src="/path/to/image.jpg"
alt="With states"
@loaded="handleLoaded"
@error="handleError"
/>
<ResponsiveImage
:sources="[
{ media: '(max-width: 600px)', srcset: '/path/to/mobile.jpg' },
{ media: '(min-width: 601px)', srcset: '/path/to/desktop.jpg' }
]"
fallback="/path/to/fallback.jpg"
alt="Responsive"
/>
</div>
</template>
<script>
import ImageComponent from './ImageComponent.vue'
import LazyImage from './LazyImage.vue'
import SmartImage from './SmartImage.vue'
import ResponsiveImage from './ResponsiveImage.vue'
export default {
components: {
ImageComponent,
LazyImage,
SmartImage,
ResponsiveImage
},
methods: {
handleImageLoaded() {
console.log('Image loaded')
},
handleLoaded() {
console.log('Image loaded successfully')
},
handleError() {
console.error('Image failed to load')
}
}
}
</script>






