vue实现表格上传头像
Vue 表格上传头像实现方案
方案一:使用 Element UI 的 Upload 组件
安装 Element UI(若未安装):
npm install element-ui
在表格列中嵌入 Upload 组件:
<el-table-column label="头像" width="180">
<template slot-scope="scope">
<el-upload
class="avatar-uploader"
action="/api/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="scope.row.avatar" :src="scope.row.avatar" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</template>
</el-table-column>
样式调整:
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar {
width: 40px;
height: 40px;
display: block;
}
处理上传逻辑:
methods: {
handleAvatarSuccess(res, file) {
this.$set(this.tableData[file.uid], 'avatar', URL.createObjectURL(file.raw))
},
beforeAvatarUpload(file) {
const isImage = file.type.includes('image/')
const isLt2M = file.size / 1024 / 1024 < 2
if (!isImage) this.$message.error('只能上传图片')
if (!isLt2M) this.$message.error('图片大小不能超过2MB')
return isImage && isLt2M
}
}
方案二:自定义上传组件
创建可复用的头像上传组件:
<template>
<div class="avatar-upload" @click="triggerUpload">
<img v-if="value" :src="value" class="avatar">
<input
type="file"
ref="fileInput"
@change="handleFileChange"
accept="image/*"
style="display: none">
</div>
</template>
<script>
export default {
props: ['value'],
methods: {
triggerUpload() {
this.$refs.fileInput.click()
},
async handleFileChange(e) {
const file = e.target.files[0]
if (!file.type.includes('image/')) return
const formData = new FormData()
formData.append('avatar', file)
try {
const res = await axios.post('/upload', formData)
this.$emit('input', res.data.url)
} catch (error) {
console.error(error)
}
}
}
}
</script>
在表格中使用自定义组件:
<el-table-column label="头像">
<template slot-scope="scope">
<avatar-upload v-model="scope.row.avatar"></avatar-upload>
</template>
</el-table-column>
方案三:拖拽上传实现
添加拖拽区域检测:
<div
class="drop-area"
@dragover.prevent="dragOver = true"
@dragleave="dragOver = false"
@drop.prevent="handleDrop">
<span v-if="dragOver">松开上传</span>
<span v-else>拖拽图片到此处</span>
</div>
处理拖拽事件:
data() {
return {
dragOver: false
}
},
methods: {
handleDrop(e) {
this.dragOver = false
const file = e.dataTransfer.files[0]
this.uploadFile(file)
}
}
后端对接注意事项
-
确保后端接口支持 multipart/form-data 格式
-
返回标准化响应格式:
{ "success": true, "url": "/uploads/avatar.jpg" } -
配置跨域支持(如需要):
// Express 示例 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*') next() })
性能优化建议
-
实现图片压缩前端处理
function compressImage(file) { return new Promise(resolve => { const reader = new FileReader() reader.onload = function(event) { const img = new Image() img.src = event.target.result img.onload = function() { const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.width = 200 canvas.height = 200 ctx.drawImage(img, 0, 0, 200, 200) canvas.toBlob(resolve, 'image/jpeg', 0.7) } } reader.readAsDataURL(file) }) } -
添加上传进度显示
<el-progress v-if="uploadProgress > 0" :percentage="uploadProgress"> </el-progress>







