Vue3+elementplus实现图片上传下载(最强实践)

 图片上传子组件:

实现照片的上传,预览,以及转成以逗号隔开的图片地址,即时监听,并发送消息到父组件。

<!-- ImageUploader.vue -->  
<template>
    <div>
        <el-upload class="avatar-uploader" :http-request="customUpload" :before-upload="beforeUpload"
            :show-file-list="false" multiple>
            <el-icon>
                <Plus style="background-color: azure;" />
            </el-icon>
        </el-upload>
        <div v-for="(image, index) in imageUrls" :key="index">
            <el-image :src="image" style="width: 100px; height: 100px" fit="cover" :preview-src-list="[image]">
                <template #placeholder>
                    <div class="image-slot">Loading<span class="dot">...</span></div>
                </template>
            </el-image>
            <el-button @click="deleteImage(image)" el-icon="">
                <el-icon>
                    <DeleteFilled />
                </el-icon>
            </el-button>
        </div>
    </div>
</template>  
    
<script setup lang="ts" name="ImageUploader">
import { computed, ref, watch } from 'vue';
import { upload } from '@/api/file'
import { ElMessage } from 'element-plus'
import emitter from '@/utils/emitter'


// 上传文件,请求接口,并且将结果存储
function customUpload(file: any) {
    let formData = new FormData();
    formData.append('file', file.file)
    upload(formData).then((response: any) => {
        const imgUrl = response.data;
        imageUrls.value.push(imgUrl);
    })
}

// 图片url
const imageUrls = ref([]);

// 计算属性,用于生成逗号隔开的图片地址字符串  
const commaSeparatedUrls = computed(() => imageUrls.value.join(','));
// 监听图片地址变化,即时发送最新数据给父组件
watch(imageUrls, () => {
    console.log('发送图片地址', commaSeparatedUrls.value)
    emitter.emit('send-imageUrls', commaSeparatedUrls.value)
}, { deep: true })

// 图片校验规则
const beforeUpload = (file: any) => {
    const isJPGOrPNG = file.type === 'image/jpeg' || file.type === 'image/png';
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isJPGOrPNG) {
        ElMessage.error('picture must be jpg/png format!')
        return false
    }
    if (!isLt2M) {
        ElMessage.error('picture size can not exceed 2MB!')
        return false
    }
    return true
};

// 删除图片
const deleteImage = (imgUrl: any) => {
    // 从imageUrls数组中删除指定的图片URL  
    imageUrls.value.splice(imgUrl, 1);
};

</script>  
    
<style scoped> .avatar-uploader {
     color: skyblue;
     font-style: normal;
 }
</style>

表单父组件:

引入图片上传子组件,接受消息,并实现挂载之后取消绑定事件,避免占用内存 

<template>
  <el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" :rules="rules" label-width="auto"
    class="demo-ruleForm" :size="formSize" status-icon>
    <el-form-item label="类型">
      <el-radio-group v-model="ruleForm.type">
        <el-radio value="0">转租</el-radio>
        <el-radio value="1">短租</el-radio>
        <el-radio value="2">长租</el-radio>
        <el-radio value="3">招租</el-radio>
      </el-radio-group>
    </el-form-item>
    <el-form-item label="标题" prop="tittle">
      <el-input v-model="ruleForm.tittle" />
    </el-form-item>
    <el-form-item label="地址" prop="address">
      <el-input v-model="ruleForm.address" />
    </el-form-item>
    <el-form-item label="介绍" prop="content">
      <el-input v-model="ruleForm.content" />
    </el-form-item>
    <el-form-item label="房间照片">
      <ImageUploader />
    </el-form-item>


    <el-form-item>
      <el-button type="primary" @click="submitForm(ruleFormRef)">
        Create
      </el-button>
      <el-button @click="resetForm(ruleFormRef)">Reset</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts" setup>
import { reactive, ref, onUnmounted } from 'vue'
import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
import { type HouseInter } from '@/types/model';
import emitter from '@/utils/emitter'
import ImageUploader from '@/components/ImageUploader.vue'

const formSize = ref<ComponentSize>('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<HouseInter>({})


const rules = reactive<FormRules<HouseInter>>({
  type: [{ required: true, message: '请选择房源类型', trigger: 'change' }],
  tittle: [{ required: true, message: '请填写标题', trigger: 'change' }],


})

// 接受图片上传子组件的图片地址最新消息
emitter.on('send-imageUrls', (value: string) => {
  ruleForm.housePhoto = value
  console.log('接收图片地址', ruleForm.housePhoto)
})
onUnmounted(() => {
  // 组件卸载之后,解绑事件
  emitter.off('send-imageUrls')
})

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log('submit!')
    } else {
      console.log('error submit!', fields)
    }
  })
}

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}
</script>

<style scoped></style>

消息工具类

import mitt from 'mitt'
import { ref } from 'vue'

let emitter = mitt()

let num = ref(0)

// 绑定事件
emitter.on('add', () => {
    console.log('add被调用了', num)
})
// 每隔1秒执行事件
setInterval(() => {
    // emitter.emit('add')
}, 1000)

setTimeout(() => {
    // 解绑事件
    emitter.off('add')
}, 5000)

export default emitter

要在Vue 3中使用Element Plus进行图片上传,你可以按照以下步骤进行操作: 1. 首先,确保你已经按照Element Plus的文档成功安装和引入了Element Plus库。 2. 在你的Vue组件中,使用`<el-upload>`标签来创建上传组件。根据你提供的描述,你可以为上传区域添加一个鼠标悬停时高亮的效果。 ```html <template> <el-upload action="your-upload-url" :show-file-list="false" :before-upload="beforeUpload" :on-success="onSuccess" :on-error="onError" class="upload-area" > <div class="upload-trigger" :class="{ 'highlight': hover }"> <i class="el-icon-plus"></i> <div class="upload-text">点击上传图片</div> </div> </el-upload> </template> ``` 在这个例子中,`action`属性指定了上传图片的URL地址,你需要将其替换成你自己的上传URL。`show-file-list`属性设置为`false`可以隐藏上传成功后的文件列表。`before-upload`、`on-success`和`on-error`属性分别对应了上传前、上传成功和上传失败的回调函数。你可以根据需要自行实现这些回调函数。 `upload-area`类是为了设置上传区域的样式,可以根据你的需求自行修改。 `highlight`类可以根据鼠标悬停状态来添加高亮效果的样式。你可以在CSS样式中定义这个类的样式。 3. 在CSS样式中添加鼠标悬停时的高亮效果。 ```css .upload-area { position: relative; width: 200px; height: 200px; border: 2px dashed #ccc; } .highlight { border-color: blue; } ``` 这是一个简单的示例,你可以根据需要自行调整样式。 4. 在Vue组件的`data`选项中定义一个`hover`属性,并在鼠标进入和离开上传区域时更新该属性的值。 ```javascript export default { data() { return { hover: false }; }, methods: { handleMouseEnter() { this.hover = true; }, handleMouseLeave() { this.hover = false; }, beforeUpload(file) { // 在上传前的操作 }, onSuccess(response, file) { // 上传成功后的操作 }, onError(error, file) { // 上传失败后的操作 } } } ``` 这里示例中的`handleMouseEnter`和`handleMouseLeave`方法分别用于处理鼠标进入和离开上传区域时的事件。你可以在这些方法中更新`hover`属性的值。 5. 在上传前、上传成功和上传失败的回调函数中实现相应的逻辑。 你可以在`beforeUpload`方法中实现上传前的操作,例如校验文件类型、大小等。 在`onSuccess`方法中,你可以获取到上传成功后服务器返回的响应数据,可以根据需要进行处理。 在`onError`方法中,你可以获取到上传失败时的错误信息,可以根据需要进行处理。 这样,你就可以在Vue 3中使用Element Plus实现图片的上传功能了。记得根据你的具体需求修改代码和样式。 element-plus.org - Upload 上传 | Element Plus: http://element***
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值