You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js实现图片加载失败时显示默认替代图片的方法

嘿,我来帮你搞定这个需求!在Vue里实现图片加载失败时显示默认图,其实有几种实用的方式,完全能替代你之前在CSHTML Razor里的实现,我给你详细拆解下:

方法1:直接使用img的@error事件(简单场景首选)

这是最直观的写法,适合单个图片或者页面里只有少数图片需要处理的场景。直接给img标签绑定@error事件,当图片加载失败时触发替换逻辑:

<template>
  <!-- 遍历产品列表的示例 -->
  <div class="product-list">
    <div v-for="product in products" :key="product.id" class="product-item">
      <img 
        :src="product.imageUrl" 
        @error="(e) => handleImageError(e)" 
        :alt="product.name"
      />
      <p>{{ product.name }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [
        { id: 1, name: '产品A', imageUrl: '/images/product-a.jpg' },
        { id: 2, name: '产品B', imageUrl: '/images/invalid-path.jpg' } // 故意写错路径模拟加载失败
      ],
      defaultImage: '/images/default-product.jpg' // 你的默认图片路径
    }
  },
  methods: {
    handleImageError(e) {
      // 替换为默认图片
      e.target.src = this.defaultImage
      // 关键:防止默认图片也加载失败时无限触发error事件
      e.target.onerror = null
    }
  }
}
</script>

这个方法的好处是逻辑清晰,不需要额外配置,直接在需要的img标签上绑定事件就行。

方法2:自定义全局指令(多页面/多组件复用首选)

如果你的网站很多地方都需要处理图片加载失败的情况,自定义一个全局指令会更高效,不用重复写事件绑定代码:

Vue 2 版本

在你的main.js里注册全局指令:

import Vue from 'vue'
import App from './App.vue'

// 注册v-img-fallback指令
Vue.directive('img-fallback', {
  bind(el, binding) {
    // 初始化设置图片src
    el.src = binding.value
    // 绑定error事件
    el.onerror = function() {
      el.src = '/images/default-product.jpg'
      el.onerror = null // 防止循环触发
    }
  },
  update(el, binding) {
    // 当绑定的图片URL变化时,重新设置src和error事件
    if (binding.value !== el.src) {
      el.src = binding.value
      el.onerror = function() {
        el.src = '/images/default-product.jpg'
        el.onerror = null
      }
    }
  }
})

new Vue({
  render: h => h(App)
}).$mount('#app')

然后在任意组件里直接使用:

<template>
  <div class="product-list">
    <div v-for="product in products" :key="product.id" class="product-item">
      <img v-img-fallback="product.imageUrl" :alt="product.name" />
      <p>{{ product.name }}</p>
    </div>
  </div>
</template>

Vue 3 版本

Vue 3的指令注册方式略有不同,在main.js里这样写:

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// 注册v-img-fallback指令
app.directive('img-fallback', {
  mounted(el, binding) {
    el.src = binding.value
    el.onerror = () => {
      el.src = '/images/default-product.jpg'
      el.onerror = null
    }
  },
  updated(el, binding) {
    if (binding.value !== el.src) {
      el.src = binding.value
      el.onerror = () => {
        el.src = '/images/default-product.jpg'
        el.onerror = null
      }
    }
  }
})

app.mount('#app')

使用方式和Vue2完全一样,只需要在img标签上加上v-img-fallback="product.imageUrl"即可。

小提示

  • 记得把示例里的默认图片路径替换成你自己的实际路径,建议把默认图片放在项目的静态资源目录里(比如Vue2的static文件夹,Vue3的public文件夹),这样不会因为打包路径问题找不到图片。
  • 加上el.onerror = null是非常必要的,万一你的默认图片也因为某种原因加载失败,这个设置可以避免触发无限循环的error事件。

内容的提问来源于stack exchange,提问作者Vishwas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:39:54