1、普通 <img>
标签(静态图片)
直接通过 src
属性指定图片路径,适用于静态资源(如存放在 public
目录下的图片)。
<template>
<img src="/images/logo.png" alt="logo" />
//或者
//<img src="@asstes/images/logo.png" alt="logo" />
</template>
特点:
- 图片路径为绝对路径,会直接映射到项目的根目录。
- 无需经过 Webpack 等构建工具处理,适合不需要编译的静态文件(如 avicon、第三方图片)。
2、动态绑定 :src
(动态图片路径)
通过 Vue 的响应式特性,使用 v-bind
(:src
)动态绑定图片路径,适用于变量控制的图片地 、址(如从后端接口获取的图片 URL)
<template>
<img :src="imageUrl" alt="Dynamic Image" />
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://example.com/image.jpg', // 可来自接口或组件状态
};
},
};
//如果使用此种方式还是不显示图片的话可以使用import 引用 (一般使用静态资源时未能获取到绝对路径)
import img1 from "@/asstes/img/picter1.png"
export default {
data() {
return {
imageUrl: img1, // 可来自接口或组件状态
};
},
};
</script>
场景:
- 加载用户头像、商品图片等后端返回的动态资源。
- 配合计算属性或 Watcher 实现更复杂的动态逻辑。
3、使用 require
引入(Webpack 处理的图片,vite同理)
当图片存放在 src
目录下(如 src/assets/images
)时,需通过 require
或 ES6 的 import
引入,适用于需要打包编译的静态资源。
<template>
<!-- 方式 1:在模板中直接 require -->
<img :src="require('@/assets/images/logo.png')" alt="Logo" />
<!-- 方式 2:在数据中提前引入 -->
<img :src="logoImg" alt="Logo" />
</template>
<script>
export default {
data() {
return {
// 方式 2:在 data 中通过 import 或 require 引入
logoImg: require('@/assets/images/logo.png'),
// 或:import logoImg from '@/assets/images/logo.png';
};
},
};
</script>
特点:
- 图片会被 Webpack 等构建工具处理,支持 ** 文件压缩、路径别名(如
@
代表src
目录)** 等功能。 - 适合项目内的静态资源管理(如主题图片、图标)。
4、使用 Vue 组件封装(自定义图片组件)
将图片渲染逻辑封装为组件,支持统一处理加载状态、错误提示等功能。
<!-- 自定义图片组件 -->
<template>
<div class="image-container">
<img
:src="src"
:alt="alt"
@load="onLoad"
@error="onError"
/>
<!-- 加载中提示 -->
<div v-show="loading" class="loading">Loading...</div>
<!-- 错误提示 -->
<div v-show="error" class="error">图片加载失败</div>
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
required: true,
},
alt: {
type: String,
default: '',
},
},
data() {
return {
loading: true,
error: false,
};
},
methods: {
onLoad() {
this.loading = false;
},
onError() {
this.error = true;
this.loading = false;
},
},
};
</script>
使用:
<template>
<CustomImage
src="https://example.com/image.jpg"
alt="Custom Image"
/>
</template>
优势:
- 解耦图片渲染逻辑,可复用加载状态、错误处理等功能。
- 方便扩展功能(如图片懒加载、图片预览等)。
补充:AI建议:
5、使用 SVG 图标(矢量图)
若需使用 SVG 图标,可直接引入或通过组件封装(如 vue-svg-icon
插件)。
<!-- 直接引入 SVG -->
<template>
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L1 21h22L12 2z" fill="currentColor" />
</svg>
</template>
<!-- 使用 vue-svg-icon 组件 -->
<template>
<svg-icon name="home" />
</template>
<script>
import { SvgIcon } from 'vue-svg-icon/ssr';
export default {
components: {
SvgIcon,
},
};
</script>
特点:
- 矢量图不模糊,适合图标类场景。
- 可通过 CSS 灵活控制颜色、尺寸等样式。
6、图片懒加载(优化性能)
对于长列表或视窗外的图片,可使用 vue-lazyload
插件实现懒加载,减少首屏请求量。
<!-- 安装插件:npm install vue-lazyload -->
<template>
<img v-lazy="imageUrl" alt="Lazy Image" />
</template>
<script>
import VueLazyload from 'vue-lazyload';
export default {
directives: {
lazy: VueLazyload,
},
data() {
return {
imageUrl: 'https://example.com/large-image.jpg',
};
},
};
</script>
配置:
Vue.use(VueLazyload, {
loading: require('@/assets/loading.gif'), // 加载中占位图
error: require('@/assets/error.jpg'), // 加载失败占位图
});
总结对比
场景 | 推荐写法 | 特点 |
---|---|---|
静态资源(public) | <img src="/path" /> | 直接引用,无需构建处理 |
动态路径(接口数据) | :src="imageUrl" | 响应式绑定,支持后端返回的 URL |
项目内资源(src) | require /import | 需经 Webpack 处理,支持路径别名和打包优化 |
复杂逻辑(加载状态) | 自定义组件 | 封装复用,可扩展加载状态、错误处理等功能 |
矢量图标 | SVG 直接引入或组件 | 高清无锯齿,支持样式灵活控制 |
性能优化(懒加载) | vue-lazyload 指令 | 减少首屏请求,适合长列表或大屏图片 |
补充:记录一个vue3 setup 中 自定组件的语法糖
当你使用 defineProps()
宏定义组件属性时:
- 类型推导与运行时绑定:Vue 会根据你提供的类型信息(如
StatsCardProps
接口),同时生成类型定义和运行时 props 选项。 - 自动注入到模板作用域:通过
defineProps()
定义的 props 会被自动注入到模板的上下文中,无需额外导入或声明。
子组件:
<script setup lang="ts">
interface StatsCardProps {
title?: string;
color?: string;
// 其他props...
}
// defineProps<StatsCardProps>() 会生成:
// - 类型定义:props.title 类型为 string | undefined
// - 运行时:等价于 props: { title: String, color: String }
</script>
<template>
<div :style="{ backgroundColor: color }">{{ title }}</div> <!-- 直接使用props -->
</template>
父组件
<cardList
:id="card.id"
:title="card.title"
:color="card.color"
/>