|
|
@ -1,33 +1,70 @@
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
|
|
|
|
<!-- 创建一个 div 元素作为整个组件内容的包裹容器,这是 HTML 中常用的用于组织和划分页面结构的方式 -->
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
|
|
|
|
<!-- el-upload 组件,用于实现文件上传功能,它是基于 Element UI 库提供的组件,方便在 Vue 项目中快速集成文件上传交互功能 -->
|
|
|
|
<el-upload
|
|
|
|
<el-upload
|
|
|
|
|
|
|
|
<!-- 通过三元表达式根据 useOss 的值来动态决定上传文件的 action 属性值,即上传文件的请求地址 -->
|
|
|
|
|
|
|
|
<!-- 如果 useOss 为 true,就使用 ossUploadUrl 作为上传地址,这通常意味着要将文件上传到阿里云 OSS(Object Storage Service,对象存储服务)服务器上 -->
|
|
|
|
|
|
|
|
<!-- 如果 useOss 为 false,则使用 minioUploadUrl 作为上传地址,MinIO 也是一种常用的对象存储服务,这里可以根据实际需求切换使用不同的存储服务来上传文件 -->
|
|
|
|
:action="useOss?ossUploadUrl:minioUploadUrl"
|
|
|
|
:action="useOss?ossUploadUrl:minioUploadUrl"
|
|
|
|
|
|
|
|
<!-- 同样基于 useOss 的值来决定是否向上传请求中传递额外的数据(以对象形式) -->
|
|
|
|
|
|
|
|
<!-- 当 useOss 为 true 时,将 dataObj 作为额外的数据传递给上传请求,这些数据一般包含了与文件上传到 OSS 相关的配置信息,例如上传策略、签名等,用于服务器验证上传的合法性 -->
|
|
|
|
|
|
|
|
<!-- 当 useOss 为 false 时,不传递额外的数据,即设置为 null -->
|
|
|
|
:data="useOss?dataObj:null"
|
|
|
|
:data="useOss?dataObj:null"
|
|
|
|
|
|
|
|
<!-- 设置文件列表在页面上的展示类型为 "picture-card",这种类型的展示效果通常是以卡片形式呈现已上传的文件(在这里主要是图片文件) -->
|
|
|
|
|
|
|
|
<!-- 每个文件会以一个独立的卡片样式展示,方便用户直观地查看已上传的文件,并且可以进行相应的操作(如删除、预览等) -->
|
|
|
|
list-type="picture-card"
|
|
|
|
list-type="picture-card"
|
|
|
|
|
|
|
|
<!-- 通过绑定计算属性 fileList,将已上传文件的相关信息以特定格式传递给 el-upload 组件,以便组件能够正确展示已上传的文件列表 -->
|
|
|
|
|
|
|
|
<!-- 计算属性 fileList 会根据组件接收到的相关数据进行处理,转化为 el-upload 组件可识别的格式(后面会在计算属性部分详细说明) -->
|
|
|
|
:file-list="fileList"
|
|
|
|
:file-list="fileList"
|
|
|
|
|
|
|
|
<!-- 绑定一个名为 before-upload 的回调函数,该函数会在每个文件上传之前被触发 -->
|
|
|
|
|
|
|
|
<!-- 可以在这个函数中进行一些前置的验证、准备工作,例如当使用阿里云 OSS 上传时,需要在这里获取并设置相关的上传策略等配置信息,决定文件是否可以进行上传 -->
|
|
|
|
:before-upload="beforeUpload"
|
|
|
|
:before-upload="beforeUpload"
|
|
|
|
|
|
|
|
<!-- 绑定一个名为 on-remove 的回调函数,当用户在已展示的文件列表中删除某个文件时,这个函数会被触发 -->
|
|
|
|
|
|
|
|
<!-- 用于处理文件删除后的相关逻辑,比如通知父组件文件列表发生了变化,让父组件可以相应地更新页面上显示的文件信息等 -->
|
|
|
|
:on-remove="handleRemove"
|
|
|
|
:on-remove="handleRemove"
|
|
|
|
|
|
|
|
<!-- 绑定一个名为 on-success 的回调函数,在文件上传成功后,该函数会被触发 -->
|
|
|
|
|
|
|
|
<!-- 可以在这个函数里进行后续的操作,例如更新文件列表数据、通知父组件上传成功的消息以及根据上传结果进行一些页面展示相关的调整等 -->
|
|
|
|
:on-success="handleUploadSuccess"
|
|
|
|
:on-success="handleUploadSuccess"
|
|
|
|
|
|
|
|
<!-- 绑定一个名为 on-preview 的回调函数,当用户点击已上传的文件进行预览操作时,这个函数会被触发 -->
|
|
|
|
|
|
|
|
<!-- 主要用于实现文件的预览功能,比如打开一个对话框展示图片的大图等操作 -->
|
|
|
|
:on-preview="handlePreview"
|
|
|
|
:on-preview="handlePreview"
|
|
|
|
|
|
|
|
<!-- 通过绑定 maxCount 属性来设置允许上传的文件最大数量,这个属性的值来源于组件通过 props 接收的父组件传递过来的 maxCount 值 -->
|
|
|
|
|
|
|
|
<!-- 限制用户最多只能上传指定数量的文件,若用户尝试上传超过此数量的文件,会触发相应的超出限制处理逻辑 -->
|
|
|
|
:limit="maxCount"
|
|
|
|
:limit="maxCount"
|
|
|
|
|
|
|
|
<!-- 绑定一个名为 on-exceed 的回调函数,当用户上传的文件数量超过了通过 :limit 设置的最大数量时,该函数会被触发 -->
|
|
|
|
|
|
|
|
<!-- 用于给出相应的提示信息,告知用户上传文件数量超出了限制,让用户知晓当前的操作不符合规定 -->
|
|
|
|
:on-exceed="handleExceed"
|
|
|
|
:on-exceed="handleExceed"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
<!-- 在 el-upload 组件内部添加一个图标元素,使用 el-icon-plus 这个类来展示一个加号图标 -->
|
|
|
|
|
|
|
|
<!-- 通常这个加号图标在界面上用于提示用户可以点击此处进行文件上传操作,是一种常见的交互设计方式 -->
|
|
|
|
<i class="el-icon-plus"></i>
|
|
|
|
<i class="el-icon-plus"></i>
|
|
|
|
</el-upload>
|
|
|
|
</el-upload>
|
|
|
|
|
|
|
|
<!-- el-dialog 组件用于创建一个对话框,用于展示图片的预览功能,它也是 Element UI 库中的组件,方便实现弹出式的展示界面 -->
|
|
|
|
<el-dialog :visible.sync="dialogVisible">
|
|
|
|
<el-dialog :visible.sync="dialogVisible">
|
|
|
|
|
|
|
|
<!-- 在对话框内部放置一个 img 元素,用于展示要预览的图片 -->
|
|
|
|
|
|
|
|
<!-- 通过绑定 src 属性为 dialogImageUrl,根据这个属性的值来确定要展示的图片的路径,从而正确显示相应的图片内容 -->
|
|
|
|
|
|
|
|
<!-- 设置图片的宽度为 100%,让图片能够自适应对话框的宽度,完整地展示出来 -->
|
|
|
|
<img width="100%" :src="dialogImageUrl" alt="">
|
|
|
|
<img width="100%" :src="dialogImageUrl" alt="">
|
|
|
|
</el-dialog>
|
|
|
|
</el-dialog>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
|
|
<script>
|
|
|
|
import {policy} from '@/api/oss'
|
|
|
|
// 从 '@/api/oss' 文件中导入 policy 函数,推测这个函数用于向服务器端请求获取与阿里云 OSS 文件上传相关的策略(Policy)信息 -->
|
|
|
|
|
|
|
|
// 例如,可能返回包含上传策略、签名、访问密钥等配置信息的对象,这些信息对于将文件安全、合法地上传到阿里云 OSS 服务是必要的,服务器会依据这些信息验证上传请求是否合规
|
|
|
|
|
|
|
|
import {policy} from '@/api/oss';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 导出一个 Vue 组件的配置对象,用于定义组件的各种属性、数据、方法等内容,这是 Vue 组件开发中常用的方式,使得组件可以在其他地方被导入和使用
|
|
|
|
export default {
|
|
|
|
export default {
|
|
|
|
|
|
|
|
// 组件的名称,用于在 Vue 实例或开发者工具中标识该组件,这里将组件命名为 'multiUpload',方便在项目中对不同组件进行区分和引用
|
|
|
|
name: 'multiUpload',
|
|
|
|
name: 'multiUpload',
|
|
|
|
|
|
|
|
// props 用于定义组件接收来自父组件传递的数据属性,它是实现父子组件通信的重要方式之一 -->
|
|
|
|
props: {
|
|
|
|
props: {
|
|
|
|
//图片属性数组
|
|
|
|
// 定义一个名为 value 的属性,其类型为数组,用于接收父组件传递过来的图片相关信息,通常是图片的路径数组 -->
|
|
|
|
|
|
|
|
// 父组件可以将已有的图片路径列表传递给这个组件,以便在组件内部进行展示、管理以及后续的上传、删除等操作相关处理 -->
|
|
|
|
value: Array,
|
|
|
|
value: Array,
|
|
|
|
//最大上传图片数量
|
|
|
|
// 定义一个名为 maxCount 的属性,用于设置允许上传的最大图片数量 -->
|
|
|
|
|
|
|
|
// 其类型为数字(Number),并且设置了默认值为 5,表示如果用户尝试上传的图片数量超过 5 张,组件将会触发相应的超出限制处理逻辑 -->
|
|
|
|
maxCount: {
|
|
|
|
maxCount: {
|
|
|
|
type: Number,
|
|
|
|
type: Number,
|
|
|
|
default: 5
|
|
|
|
default: 5
|
|
|
@ -35,6 +72,8 @@
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
|
|
|
|
// 创建一个名为 dataObj 的对象,用于存储与文件上传相关的配置信息,特别是在使用阿里云 OSS 上传时,这个对象的各个属性会被赋予相应的值 -->
|
|
|
|
|
|
|
|
// 例如,policy 属性用于存储上传策略,signature 属性存储签名信息,ossaccessKeyId 属性存储访问密钥 ID,这些信息共同保障文件能够正确上传到 OSS 服务 -->
|
|
|
|
dataObj: {
|
|
|
|
dataObj: {
|
|
|
|
policy: '',
|
|
|
|
policy: '',
|
|
|
|
signature: '',
|
|
|
|
signature: '',
|
|
|
@ -43,14 +82,27 @@
|
|
|
|
dir: '',
|
|
|
|
dir: '',
|
|
|
|
host: ''
|
|
|
|
host: ''
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义一个名为 dialogVisible 的属性,用于控制图片预览对话框的可见性,初始值设为 false -->
|
|
|
|
|
|
|
|
// 意味着在组件初始化时,图片预览对话框是隐藏的,只有当用户触发图片预览操作时,才会将这个值设为 true,使对话框显示出来展示相应的图片 -->
|
|
|
|
dialogVisible: false,
|
|
|
|
dialogVisible: false,
|
|
|
|
|
|
|
|
// 定义一个名为 dialogImageUrl 的属性,用于存储当前正在预览的图片的路径,初始值设为 null -->
|
|
|
|
|
|
|
|
// 当用户点击某张已上传的图片进行预览时,会将对应的图片路径赋值给这个属性,以便对话框中的 img 元素能够根据这个路径正确展示图片内容 -->
|
|
|
|
dialogImageUrl: null,
|
|
|
|
dialogImageUrl: null,
|
|
|
|
useOss:false, //使用oss->true;使用MinIO->false
|
|
|
|
// 定义一个名为 useOss 的布尔值属性,用于判断当前组件使用的文件存储服务是阿里云 OSS(值为 true 时)还是 MinIO(值为 false 时) -->
|
|
|
|
|
|
|
|
// 根据这个属性的值,组件内部的多个逻辑(如文件上传地址选择、是否需要获取特定配置等)会做出相应的区分和处理 -->
|
|
|
|
|
|
|
|
useOss: false,
|
|
|
|
|
|
|
|
// 定义一个名为 ossUploadUrl 的属性,用于存储阿里云 OSS 文件上传的请求地址 -->
|
|
|
|
|
|
|
|
// 这里是一个示例地址,在实际应用中需要根据具体的阿里云 OSS 配置进行调整,当 useOss 为 true 时,文件上传操作会使用这个地址向阿里云 OSS 服务发送上传请求 -->
|
|
|
|
ossUploadUrl: 'http://macro-oss.oss-cn-shenzhen.aliyuncs.com',
|
|
|
|
ossUploadUrl: 'http://macro-oss.oss-cn-shenzhen.aliyuncs.com',
|
|
|
|
|
|
|
|
// 定义一个名为 minioUploadUrl 的属性,用于存储 MinIO 文件上传的请求地址 -->
|
|
|
|
|
|
|
|
// 同样是一个示例地址,当 useOss 为 false 时,文件上传操作会使用这个地址向 MinIO 服务发送上传请求,MinIO 是一种开源的对象存储服务,可自行搭建并部署在本地或私有环境中 -->
|
|
|
|
minioUploadUrl: 'http://localhost:8080/minio/upload',
|
|
|
|
minioUploadUrl: 'http://localhost:8080/minio/upload',
|
|
|
|
};
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
computed: {
|
|
|
|
|
|
|
|
// 定义一个计算属性 fileList,它会根据组件接收到的父组件传递过来的 value(图片路径数组)进行相应的处理 -->
|
|
|
|
|
|
|
|
// 通过循环遍历 value 数组中的每个元素,为每个图片路径创建一个包含 url 属性的对象,并将这些对象依次添加到新创建的 fileList 数组中,最后返回这个 fileList 数组 -->
|
|
|
|
|
|
|
|
// 这样处理后的 fileList 数组就是 el-upload 组件能够识别的文件列表格式,用于在组件中正确展示已上传的图片文件列表 -->
|
|
|
|
fileList() {
|
|
|
|
fileList() {
|
|
|
|
let fileList = [];
|
|
|
|
let fileList = [];
|
|
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
|
@ -60,6 +112,8 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
// 定义一个名为 emitInput 的方法,用于向父组件触发一个名为 'input' 的自定义事件,并传递经过处理后的文件列表数据(以只包含图片路径的数组形式) -->
|
|
|
|
|
|
|
|
// 在组件内部的多个地方(如文件上传成功、文件删除等操作后)会调用这个方法,通过触发这个事件告知父组件文件列表数据发生了变化,使得父组件可以根据接收到的新数据进行相应的更新操作,实现子组件与父组件之间的数据交互和同步 -->
|
|
|
|
emitInput(fileList) {
|
|
|
|
emitInput(fileList) {
|
|
|
|
let value = [];
|
|
|
|
let value = [];
|
|
|
|
for (let i = 0; i < fileList.length; i++) {
|
|
|
|
for (let i = 0; i < fileList.length; i++) {
|
|
|
@ -67,13 +121,24 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.$emit('input', value)
|
|
|
|
this.$emit('input', value)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 handleRemove 方法,用于处理文件删除操作 -->
|
|
|
|
|
|
|
|
// 当用户在 el-upload 组件展示的已上传文件列表中删除某个文件时,该方法会被触发,在方法内部调用 emitInput 方法并传入更新后的文件列表(fileList 参数) -->
|
|
|
|
|
|
|
|
// 这样就可以通知父组件文件列表发生了改变,父组件接收到通知后可以相应地更新页面上显示的文件列表等相关内容 -->
|
|
|
|
handleRemove(file, fileList) {
|
|
|
|
handleRemove(file, fileList) {
|
|
|
|
this.emitInput(fileList);
|
|
|
|
this.emitInput(fileList);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 handlePreview 方法,用于处理文件预览操作 -->
|
|
|
|
|
|
|
|
// 当用户点击已上传的图片触发预览功能时,这个方法会被调用,首先将 dialogVisible 属性设置为 true,使得图片预览对话框显示出来 -->
|
|
|
|
|
|
|
|
// 然后将当前点击的图片的路径(file.url)赋值给 dialogImageUrl 属性,以便对话框中的 img 元素能够根据这个路径正确展示对应的图片内容,实现图片预览功能 -->
|
|
|
|
handlePreview(file) {
|
|
|
|
handlePreview(file) {
|
|
|
|
this.dialogVisible = true;
|
|
|
|
this.dialogVisible = true;
|
|
|
|
this.dialogImageUrl = file.url;
|
|
|
|
this.dialogImageUrl = file.url;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 beforeUpload 方法,用于在文件上传前进行相关的预处理操作 -->
|
|
|
|
|
|
|
|
// 如果当前组件配置为不使用阿里云 OSS(即 useOss 为 false),则直接返回 true,表示不需要进行额外的配置获取等操作,可以直接进行文件上传 -->
|
|
|
|
|
|
|
|
// 如果使用阿里云 OSS(useOss 为 true),则需要通过调用 policy 函数向服务器请求获取文件上传所需的策略等配置信息 -->
|
|
|
|
|
|
|
|
// 在获取到信息后,将相应的值填充到 dataObj 对象的各个属性中,然后通过 resolve(true) 表示预处理成功,允许文件继续进行上传操作 -->
|
|
|
|
|
|
|
|
// 如果在获取配置信息过程中出现错误(通过 catch 捕获异常),则通过 reject(false) 表示上传预处理失败,阻止文件进行上传 -->
|
|
|
|
beforeUpload(file) {
|
|
|
|
beforeUpload(file) {
|
|
|
|
let _self = this;
|
|
|
|
let _self = this;
|
|
|
|
if (!this.useOss) {
|
|
|
|
if (!this.useOss) {
|
|
|
@ -95,6 +160,12 @@
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 handleUploadSuccess 方法,用于处理文件上传成功后的操作 -->
|
|
|
|
|
|
|
|
// 首先根据组件是否使用 OSS(通过 useOss 属性判断)来确定获取上传后文件路径的方式 -->
|
|
|
|
|
|
|
|
// 如果使用 OSS,就通过拼接 dataObj.host(主机地址)、dataObj.dir(文件存储目录)和文件名称(file.name)来生成完整的文件访问路径 -->
|
|
|
|
|
|
|
|
// 如果不使用 OSS,则直接使用服务器返回的文件路径(res.data.url) -->
|
|
|
|
|
|
|
|
// 然后将包含新上传文件信息(文件名和路径)的对象添加到 fileList 中,更新文件列表数据 -->
|
|
|
|
|
|
|
|
// 最后调用 emitInput 方法通知父组件文件列表已更新,以便父组件可以根据新的数据展示新上传的图片以及进行其他相关的页面更新操作 -->
|
|
|
|
handleUploadSuccess(res, file) {
|
|
|
|
handleUploadSuccess(res, file) {
|
|
|
|
let url = this.dataObj.host + '/' + this.dataObj.dir + '/' + file.name;
|
|
|
|
let url = this.dataObj.host + '/' + this.dataObj.dir + '/' + file.name;
|
|
|
|
if (!this.useOss) {
|
|
|
|
if (!this.useOss) {
|
|
|
@ -104,6 +175,10 @@
|
|
|
|
this.fileList.push({name: file.name, url: url});
|
|
|
|
this.fileList.push({name: file.name, url: url});
|
|
|
|
this.emitInput(this.fileList);
|
|
|
|
this.emitInput(this.fileList);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// 定义 handleExceed 方法,用于处理上传文件数量超出限制的情况 -->
|
|
|
|
|
|
|
|
// 当用户尝试上传的文件数量超过了通过 maxCount 属性设定的最大数量时,这个方法会被触发 -->
|
|
|
|
|
|
|
|
// 通过 $message 方法弹出一个警告类型的提示框,告知用户最多只能上传的图片数量(使用 this.maxCount 获取设定的最大数量) -->
|
|
|
|
|
|
|
|
// 并且设置提示框的显示时长为 1000 毫秒(即 1 秒),让用户清楚知晓当前的操作不符合上传数量限制要求 -->
|
|
|
|
handleExceed(files, fileList) {
|
|
|
|
handleExceed(files, fileList) {
|
|
|
|
this.$message({
|
|
|
|
this.$message({
|
|
|
|
message: '最多只能上传' + this.maxCount + '张图片',
|
|
|
|
message: '最多只能上传' + this.maxCount + '张图片',
|
|
|
@ -117,5 +192,3 @@
|
|
|
|
<style>
|
|
|
|
<style>
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|