vue-ImageUpload图片上传组件

举报
林太白 发表于 2025/01/28 22:35:31 2025/01/28
【摘要】 ImageUpload图片上传组件

ImageUpload图片上传组件

(1)搭建组件

这部分我们简单封装一个图片上传组件,方便我们上传图片

☞ 新建 src => components => ImageUpload => index.vue

简单搭建一个图片上传组件

<template>
	<div>ImageUpload</div>
</template>

(2)注册组件

☞ 在main.ts注册组件

import ImageUpload from '@/components/ImageUpload/index.vue' //组件-图片上传
app.component('ImageUpload', ImageUpload) //组件-图片上传

(3)功能实现

接下来我们先在这里写一个上传头像的功能组件,然后我们再进行优化

  • 实现上传头像

先调用一下我们的上传头像,注意我们上传时候要更改上传的请求头格式

🌤 关于请求headers可以查看这篇文章

::: tip
http请求
:::

// 上传图片
export function uploadImage(data) {
  return request({
    url: '/upload/image', 
    method: 'post',
    data: data,
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  })
}
  • 引入接口
import { uploadImage} from "@/api/common/common";
  • 实现上传功能
<template>
    <div>
        <el-upload class="avatar-uploader" action="#" :show-file-list="false" :before-upload="beforeAvatarUpload" :http-request="uploadPicImg" :on-success="handleAvatarSuccess">
            <img v-if="imageUrl" :src="imageUrl" class="imgavatar" />
            <el-icon v-else class="avatar-uploader-icon">
                <Plus />
            </el-icon>
        </el-upload>
    </div>
</template>
<script setup>
import { ref, reactive, toRefs, onMounted } from 'vue'

import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

import { uploadImage} from "@/api/common/common";

const imageUrl = ref('')


// 文件上传前的验证
const beforeAvatarUpload = (file) => {
    const isImage = file.type.startsWith('image/');
    const isLt2M = file.size / 1024 / 1024 < 10; // 限制文件大小为10MB
    if (!isImage) {
        this.$message.error('只能上传图片文件!');
    }
    if (!isLt2M) {
        this.$message.error('上传图片大小不能超过 2MB!');
    }
    return isImage && isLt2M;
};


// 上传图片接口
const uploadPicImg = async (query) => {
    // 确保传入的是文件对象
    let file = query.file;
    if (!file) {
        alert('请选择文件');
        return;
    }
    const formData = new FormData();
    formData.append('img', file);
    try {
        // 调用上传图片的API函数
        const res = await uploadImage(formData);
        console.log('上传', res);
        if (res.code === 200) {
            console.log('图片上传成功', res);
            ElMessage.success(res.message);
            imageUrl.value = res.imgurl; // 假设返回的数据包含图片 URL
        } else {
            ElMessage.error(res.message);
            console.error('上传失败', res);
        }
    } catch (error) {
        console.error('上传失败,网络错误', error);
    }
};
</script>
<style>
.imgavatar {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
    object-fit: cover;
}
</style>

到这里我们就实现了我们上传图片的功能!

(4)组件封装

接下来我们就简单封装一下这个组件,方便我们使用,定义一下传递参数以及提交参数

// Props
const props = defineProps({
  action: {
    type: String,
    required: true
  },
  maxSize: {
    type: Number,
    default: 10 // 默认最大文件大小为10MB
  }
});

// Emits
const emit = defineEmits(['update:imageUrl']);


成功以后提交给父组件
emit('update:imageUrl', res.imgurl); // 将图片URL通过事件传递给父组件

  • 父组件之中使用子组件

父组件使用 UploadImage 组件,我们可以在其中自定义上传接口地址和最大文件大小,然后在子组件成功上传后将图片URL通过事件传递给父组件。

<template>
  <div>
    <h2>头像上传</h2>
    <!-- 使用封装好的 UploadImage 组件 -->
    <UploadImage 
      :action="'/upload/image'" 
      :maxSize="5" 
      @update:imageUrl="handleImageUrlUpdate" />
    <div v-if="imageUrl">
      <p>上传的图片 URL: {{ imageUrl }}</p>
      <img :src="imageUrl" alt="上传的头像" class="uploaded-image" />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import UploadImage from '@/components/UploadImage.vue'

const imageUrl = ref('')

// 更新图片URL
const handleImageUrlUpdate = (url) => {
  imageUrl.value = url;
}
</script>

<style scoped>
.uploaded-image {
  width: 150px;
  height: 150px;
  object-fit: cover;
}
</style>

(5)组件优化

但是我们这种组件方法使用起来感觉并不好用,因为我们习惯v-model双向绑定数值,所以我们可以进行一下优化

  • 更新组件初始状态

// Emits
const emit = defineEmits(['update:modelValue']); // 触发更新 modelValue 的事件


// 组件状态
const imageUrl = ref(props.modelValue) // 使用传入的 modelValue 初始化

// 监听 props.modelValue 的变化,保持父子组件同步
watch(() => props.modelValue, (newVal) => {
  imageUrl.value = newVal;
});
  • 在父组件之中使用
<template>
    <div>
        <h1>我是admin主页</h1>
        <div>
            <ImageUpload v-model="imgurl" :maxSize="5" />
            <div v-if="imgurl">
                <p>上传的图片 URL: {{ imgurl }}</p>
                <img :src="imgurl" alt="上传的头像" class="uploaded-image" />
            </div>
        </div>
    </div>
</template>
<script setup>
import { ref,watch } from 'vue'

// 存储上传的图片 URL
const imgurl = ref('');

// 监听 imgurl 的变化,并在变化时输出新值
watch(imgurl, (newUrl) => {
  console.log('图片 URL 已更新:', newUrl);
});

</script>
<style scoped>
.uploaded-image {
    width: 150px;
    height: 150px;
    object-fit: cover;
}
</style>

好了,接下来就可以快乐的使用我们的上传图片组件了

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。