当前位置:首页 > VUE

vue实现图片组件

2026-02-18 18:51:11VUE

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>

使用方法:

vue实现图片组件

<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"
/>

这些方法提供了从基础到高级的图片组件实现方案,可以根据项目需求选择适合的方式或组合使用多种功能。

标签: 组件图片
分享给朋友:

相关文章

vue实现组件跟随

vue实现组件跟随

实现组件跟随的常见方法 使用CSS定位 通过CSS的position: fixed或position: absolute属性实现组件跟随。需要结合JavaScript计算目标元素的位置。 <t…

css动画制作图片

css动画制作图片

CSS动画制作图片的方法 使用CSS动画可以为图片添加各种动态效果,提升网页的视觉吸引力。以下是几种常见的CSS动画实现方式: 关键帧动画(@keyframes) 通过定义关键帧来控制动画的各个阶段…

vue哪个组件实现动画

vue哪个组件实现动画

在Vue中实现动画效果,可以通过以下组件和方法实现: Vue内置动画组件 Vue提供了<transition>和<transition-group>两个内置组件,用于处理进入…

vue实现组件

vue实现组件

Vue 实现组件的方法 Vue 中实现组件可以通过多种方式,包括全局注册、局部注册、单文件组件(SFC)等。以下是常见的实现方法。 全局注册组件 全局注册的组件可以在任何 Vue 实例或组件中使用。…

vue实现组件跟随

vue实现组件跟随

Vue 实现组件跟随效果 实现组件跟随效果通常需要监听鼠标或触摸事件,动态更新组件位置。以下是几种常见实现方式: 使用鼠标事件绑定 <template> <div class=…

vue实现图片预览

vue实现图片预览

实现图片预览功能 在Vue中实现图片预览功能可以通过多种方式完成,常见的有使用原生HTML5的<dialog>元素、第三方库如viewer.js或vue-photo-preview,以及自…