单图片上传组件
ImageOneComponent.vue
<!-- 单图片上传 -->
<!-- 注意修改上传接口、Token -->
<template>
<div>
<el-upload
class="avatar-uploader"
:action="api + '/manage/file/upload'"
:headers="{ token: store.token }"
:show-file-list="false"
:on-success="imageUploadSuccess"
:before-upload="imageUploadBefore">
<el-image
v-if="mv"
class="avatar"
style="width: 178px; height: 178px"
:src="mv"
fit="cover" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, watch } from 'vue'
// 注意store的位置,这里用的Pinia,注意名称
import { sysStore } from '../store'
import { Plus } from '@element-plus/icons-vue'
// 这里是多环境配置中的接口地址
let api = import.meta.env.env_http_api
// 名称需要与Pinia导出一致
const store = sysStore()
const props = defineProps({
modelValue: {
type: String,
default: ''
}
})
const mv = ref(props.modelValue)
const { emit } = getCurrentInstance()
watch(
() => props.modelValue,
() => {
mv.value = props.modelValue
}
)
// 图片上传前
function imageUploadBefore() {}
// 图片上传成功
function imageUploadSuccess(res) {
console.log(res)
emit('update:modelValue', res.data)
}
</script>
<style scoped lang="scss">
.avatar-uploader {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 178px;
height: 178px;
transition: var(--el-transition-duration-fast);
img {
width: 100%;
}
}
.avatar-uploader:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 20px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
</style>
使用方式
import ImageOneComponent from './ImageOneComponent.vue'
<ImageOneComponent v-model="modifyData.req.cover" />
多图片上传组件
ImageMoreComponent.vue
<!-- 多图片上传,适用于英文逗号分隔的字符串 -->
<!-- 注意修改上传接口、Token -->
<template>
<div>
<el-upload
:action="api + '/manage/file/upload'"
:headers="{ token: store.token }"
v-model:file-list="fileList"
list-type="picture-card"
:on-success="imageUploadSuccess"
:before-upload="imageUploadBefore">
<el-icon class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, watch } from 'vue'
// 注意store的位置,这里用的Pinia,注意名称
import { sysStore } from '../store'
import { Plus } from '@element-plus/icons-vue'
// 这里是多环境配置中的接口地址
let api = import.meta.env.env_http_api
// 名称需要与Pinia导出一致
const store = sysStore()
const props = defineProps({
modelValue: {
type: String,
default: ''
}
})
const fileList = ref([])
// 将 modelValue 字符串转为 fileList 数组
function parseModelValue(val) {
if (!val) return []
return val.split(',').map((url) => ({
name: url,
url
}))
}
// 初始化 fileList
fileList.value = parseModelValue(props.modelValue)
const { emit } = getCurrentInstance()
watch(
() => fileList.value,
(newVal) => {
const urls = newVal.map((file) => file.url).join(',')
emit('update:modelValue', urls)
},
{ deep: true }
)
// 图片上传前
function imageUploadBefore() {}
// 图片上传成功回调
function imageUploadSuccess(res) {
if (res.code === 200) {
// 添加新文件对象到 fileList
fileList.value.push({
name: 1,
url: res.data
})
// 过滤name不为1的图片
fileList.value = fileList.value.filter((item) => item.name === 1)
console.log(fileList.value)
}
}
</script>
<style scoped lang="scss">
// 清除动画效果
::v-deep .el-upload-list__item {
transition: none !important;
}
/* 无效就移动到全局 */
/* 多图上传,关闭预览功能和删除文字提示 */
.el-upload-list__item-preview,
.el-icon--close-tip {
display: none !important;
}
/* 多图上传,调整删除图片居中 */
.el-upload-list__item-delete {
margin-left: 0 !important;
}
</style>
使用方式
import ImageMoreComponent from './ImageMoreComponent.vue'
<ImageMoreComponent v-model="modifyData.req.images" />
大文件
https://help.aliyun.com/zh/oss/user-guide/upload-files-using-presigned-urls#7de0f0f8414ze