vue3实现文件上传
代码】vue3实现文件上传。
·
我们要实现如下图所示效果
<template>
<div class="form-tr" v-for="(item, index) in fileInfo" :key="index">
<div class="title">{{item.fileName}}</div>
<div class="widget-container">
<div class="file-outer">
<input type="file"
:id="index"
hidden
:accept="accept" //accept设为只接受pdf文件
@change="onChange($event, index)">
<div class="file" @mouseenter="mouseEnterFile(index, i)" @mouseleave="mouseLeaveFile" v-for="(list, i) in item.fileList" :key="i">
<input type="text" :id="index+'id'+i" v-model="list.fileName" class="file-input" disabled/> //放文件的input框设置为不可编辑状态
<div class="hidden-div">{{list.fileName}}</div> //这个div的作用是占位 设置为不可见
<i class="delete iconfont icon-cha14" v-if="showDelete === (index + 'id' + i) && item.permission" @click="deleteFile(index, i)"></i> //删除文件图标 通过permission来控制是否有删除权限
</div>
</div>
<div class="button-group">
<i class="iconfont icon-yuanlishi history" title="查看历史" v-if="item.fileList.length > 0"></i> //查看历史图标
<i class="icon iconfont icon-tijiao5" @click="btnChange(index)" title="上传附件" v-if="item.permission"></i> //上传文件图标
</div>
</div>
</div>
</template>
<script>
import {defineComponent, reactive, ref, onMounted} from 'vue';
import all_flow_tables from '@/api/all_flow_tables' // all_flow_tables 放接口的文件名
import notify from 'devextreme/ui/notify'; //notify来于devextreme ui 控件,信息提示
export default defineComponent({
setup() {
const fileInfo = reactive([])
onMounted(() => {
let taskId = 'cb0ce517-0bfb-11ed-90d1-f8633fe87771'
all_flow_tables.getFileInfo(taskId).then(data => { // 从后台接口获取基本信息
let Data = data.data
fileInfo.push(...Data)
})
})
const position = ref('top center') //设置信息提示的位置
const showDelete = ref(-1) //删除图标的显示
const accept = ref('application/pdf') //设置上传的文件格式为pdf
const btnChange = (index) => { //点击上传文件图标后获取id为index的input
let file = document.getElementById(index)
file.click() //然后执行该input的点击事件,然后调用onChange
}
const onChange = (e, index) => {
let currentFile = e.target.value.slice(12) // 获取当前选择的文件并截取文件名
let files = e.target.files[0] //获取当前选择上传的文件(需要传给后台)
fileInfo[index].fileList.push({ //将获取的文件名放入fileInfo中并展示在页面中
fileName: currentFile
})
let fileType = fileInfo[index].fileType
let taskId = 'cb0ce517-0bfb-11ed-90d1-f8633fe87771'
let formData = new FormData()
formData.append('file', files)
all_flow_tables.postUploadAppendix(fileType,taskId,formData).then(response=>{
notify({ // 文件上传成功后的信息弹出提示
width: 250,
height: 40,
message: response.data,
position: position.value,
type: 'success'
})
})
}
const mouseEnterFile = (index, i) => { // 鼠标经过的文件 显示删除按钮
let id = index + 'id' + i
if(document.getElementById(id).value) {
showDelete.value = index + 'id' + i
}
}
const mouseLeaveFile = () => { //删除按钮隐藏
showDelete.value = -1
}
const deleteFile = (index, i) => { // 删除文件
let id = fileInfo[index].fileList[i].id
let taskId = 'cb0ce517-0bfb-11ed-90d1-f8633fe87771'
all_flow_tables.deleteAppendix(id, taskId).then(response => {
if (response.code === 0) {
notify({
width: 250,
height: 40,
message: '删除成功',
position: position.value,
type: 'success',
})
fileInfo[index].fileList[i].fileName = ''
showDelete.value = -1
}
})
}
return {
fileInfo,
position,
accept,
showDelete,
btnChange,
onChange,
mouseEnterFile,
mouseLeaveFile,
deleteFile
}
},
components: {
// DxFileUploader
},
})
</script>
<style scoped lang="scss">
.form-tr{
width: 100%;
height: auto;
min-height: 50px;
position: relative;
display: flex;
align-items: center;
justify-content: flex-start;
border-bottom: 1px solid #99a0cd8c;
.title{
width: 149px;
height: auto;
min-height: 49px;
text-align: left;
display: flex;
align-items: center;
padding: 7px 10px;
background-color: #fbfeff;
font-size: 13px;
position: absolute;
top: 0;
bottom: 0;
}
.opinion{
width: calc(100% - 200px);
height: 100px;
.sign{
width: 50%;
height: 30px;
line-height: 4;
font-size: 18px;
font-weight: 600;
}
.cont{
width: 100%;
height: 70px;
.seal{
width: 50%;
height: 100%;
float: left;
display: flex;
align-items: center;
justify-content: space-evenly;
img{
width: 100px;
}
}
.date{
width: 45%;
height: 80%;
display: flex;
justify-content: flex-end;
align-items: flex-end;
font-size: 18px;
}
}
}
}
.form-tr:last-child{
border: 0;
}
.widget-container{
width: calc(100% - 150px);
min-height: 55px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
margin-left: 149px;
border-left: 1px solid #99a0cd8c;
.file-outer{
width: calc(100% - 100px);
.file{
text-align: left;
margin: 5px 0;
width: 100%;
position: relative;
display: flex;
align-items: center;
.file-input{
border: 0;
background-color: unset;
width: 100%;
position: absolute;
}
.hidden-div{
width: auto;
display: contents;
visibility: hidden;
}
.delete{
color: #ffb2b2;
font-size: 13px;
cursor: pointer;
margin-left: 10px;
z-index: 1;
}
.delete:hover{
color: red;
font-weight: bold;
}
}
}
.button-group{
width: 80px;
display: flex;
align-items: center;
justify-content: end;
.history{
color: darksalmon;
font-size: 16px;
cursor: pointer;
margin-right: 10px;
}
.icon-tijiao5{
color: #00a58a;
margin-right: 5px;
font-size: 18px;
cursor: pointer;
}
}
}
</style>
更多推荐
已为社区贡献5条内容
所有评论(0)