当前位置:首页 > 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组件

Vue 组件的基本实现 Vue 组件是 Vue.js 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种方式: 单文件组件 (SFC) 使用 .vue 文件格式,…

vue实现图片打点

vue实现图片打点

实现图片打点的基本思路 图片打点功能通常指在图片上添加可交互的标记点,点击或悬停时显示相关信息。Vue实现该功能需要结合DOM操作和事件监听。 核心步骤 准备图片和容器 在Vue组件中设置一个相对定…

vue实现穿梭框树组件

vue实现穿梭框树组件

Vue 穿梭框树组件实现 穿梭框树组件通常结合了树形结构和穿梭框功能,允许用户在左右两栏之间移动树节点数据。以下是基于 Vue 的实现方案: 核心功能设计 数据结构 树形数据通常采用嵌套结构,例如:…

实现vue组件

实现vue组件

创建 Vue 组件 Vue 组件可以通过单文件组件(.vue 文件)或直接在 JavaScript 中定义。以下是两种常见实现方式。 单文件组件方式 单文件组件包含模板、脚本和样式三部分,适合复杂项…

react如何引用图片

react如何引用图片

在React中引用图片的方法 使用import直接引入图片 在React组件中,可以通过import语句将图片作为模块引入。这种方式适合在组件内部使用图片,Webpack会处理图片的路径和打包。 i…

js实现图片

js实现图片

图片加载与显示 在JavaScript中,可以通过Image对象动态加载图片。创建实例后设置src属性触发加载,通过onload回调处理加载完成后的操作: const img = new Ima…