JavaScript

超轻量级php框架startmvc

vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)

更新时间:2020-09-17 14:48:01 作者:startmvc
说在前面网上有很多种文件上传的方法,根据公司最近的业务需求,要求实现多种文件的上

说在前面

网上有很多种文件上传的方法,根据公司最近的业务需求,要求实现多种文件的上传,在实现过程中,查阅了很多资料,最后,终于把功能实现了,开心!


<template>
 <div>
 <v-header :left-text="`上传${columnName}`"></v-header>

 <div class="upload">
 <div v-if="columnName === '视频'">
 <div class="forPreview_video" v-for="(item, index) in uploadVideoList" :key="index">
 <video :src="videoSrc"></video>
 <van-icon name="delete" @click="delBtn(index)" class="delte"/>
 </div>
 <van-uploader v-show="uploadVideoList.length < 2" preview-size="80px" accept="video/*" :before-read="beforeRead" :after-read="afterRead"></van-uploader>
 </div>

 <div v-if="columnName === '文档'">
 <div class="forPreview_doc" v-for="(item, index) in uploadDocList" :key="index">
 <img src="../../assets/img/resource_doc_b@2x.png" alt="">
 <span>{{item.name}}</span>
 <span>{{item.size | formatSize}}</span>
 <van-icon name="delete" @click="delBtn(index)" class="delte"/>
 </div>
 <van-uploader v-show="uploadDocList.length < 2" preview-size="80px" accept=".doc, .docx, .xml, .xlsx, .pdf" :before-read="beforeRead" :after-read="afterRead"></van-uploader>
 </div>

 <div v-if="columnName === '音频'">
 <div class="forPreview_audio" v-for="(item, index) in uploadAudioList" :key="index">
 <img src="../../assets/img/resource_audio@2x.png" alt="">
 <span>{{item.name}}</span>
 <span>{{item.size | formatSize}}</span>
 <van-icon name="delete" @click="delBtn(index)" class="delte"/>
 </div>
 <van-uploader v-show="uploadAudioList.length < 2" preview-size="80px" accept="audio/*" :before-read="beforeRead" :after-read="afterRead"></van-uploader>
 </div>

 <div v-if="columnName === '图片'">
 <div class="forPreview_pic" v-for="(item, index) in uploadPicList" :key="index">
 <img :src="picSrc" alt="">
 <van-icon name="delete" @click="delBtn(index)" class="delte"/>
 </div>
 <van-uploader v-show="uploadPicList.length < 2" accept="image/*" preview-size="80px" :before-read="beforeRead" :after-read="afterRead"></van-uploader>
 </div>

 <div class="diy-submit">
 <van-button @click="doSubmit($event)">提交</van-button>
 </div>
 </div>
 </div>
</template>

上述html代码是在同一页面根据前一页面传回的columnName的值来判断需要上传哪种类型文件。


<script>
 import VHeader from '../../common/header'
 import {classifyList, uploadFile, addResources} from '../../http/mock'
 import Toast from 'vant'
 export default {
 name: "uploadFile",
 components: {
 VHeader
 },
 data(){
 return{
 tagList: [], 
 uploadTitle: '',
 currentTag: null,
 tagId: null,
 columnName: localStorage.getItem('columnName'),
 fileIdArr: [],

 uploadVideoList: [], // 选中的上传视频列表
 videoSrc: '', // 选中的视频的src,用来显示视频
 uploadDocList: [], // 选中的上传文档列表
 uploadAudioList: [], // 选中的上传音频列表
 uploadPicList: [], // 选中的上传图片列表
 picSrc: '', // 选中的图片的src,用来显示图片缩略图
 }
 },
 filters: {
 formatSize(val) { // 格式化文件大小
 if (val > 0) {
 return (val / 1024 / 1024).toFixed(2) + 'M';
 } else {
 return '0M';
 }
 },
 },
 methods: {
 // vant上传文件前校验文件事件
 // 文件选中后先提交给后台,后台根据选中的文件,返回数组(这一业务根据后台而定)
 beforeRead(file){
 let formData = new FormData(); // 为上传文件定义一个formData对象
 let config = {
 headers: {
 'Content-Type': 'multipart/form-data'
 }
 };
 let uploadUrl = URL.createObjectURL(file); // 将选中的上传文件转化为二进制文件,显示在页面上
 if(this.columnName === '视频'){
 this.uploadVideoList.push(file);
 this.videoSrc = uploadUrl;
 // 这里使用foreach是为了将选中的多个文件都添加进定义的formdata变量中
 this.uploadVideoList.forEach(item => {
 formData.append(item.name, item)
 })
 }else if(this.columnName === '文档'){
 this.uploadDocList.push(file);
 this.uploadDocList.forEach(item => {
 formData.append(item.name, item)
 })
 }else if(this.columnName === '音频'){
 this.uploadAudioList.push(file);
 this.uploadAudioList.forEach(item => {
 formData.append(item.name, item)
 })
 }else if(this.columnName === '图片'){
 this.uploadPicList.push(file);
 this.picSrc = uploadUrl;
 this.uploadPicList.forEach(item => {
 formData.append(item.name, item)
 })
 }


 // formData.append(file.name, file); // 单个文件上传时可以这么写,上面的foreach就可以删掉
 this.$api.post(uploadFile, formData, config).then(res => {
 this.fileIdArr = res.data.data; // 把選中的文件傳送給後台
 }).catch(err => {
 Toast('文件上傳失敗!')
 })
 },
 // 删除待上传的文件
 delBtn(index){
 if(this.columnName === '视频'){
 // 先判断当前的选中的索引是否是在有效范围中,如果不是则跳出方法 
 if(isNaN(index) || index >= this.uploadVideoList.length){
 return false;
 }
 let tmp = [];
 // 将没被选中的上传文件存放进一个临时数组中
 for(let i = 0; i < this.uploadVideoList.length; i++){
 if(this.uploadVideoList[i] !== this.uploadVideoList[index]){
 tmp.push(this.uploadVideoList[i]);
 }
 }
 // 存放当前未被选中的上传文件
 this.uploadVideoList = tmp;
 }

 if(this.columnName === '文档'){
 console.log(this.uploadDocList.length)
 if(isNaN(index) || index >= this.uploadDocList.length){
 return false;
 }
 let tmp = [];
 for(let i = 0; i < this.uploadDocList.length; i++){
 if(this.uploadDocList[i] !== this.uploadDocList[index]){
 tmp.push(this.uploadDocList[i]);
 }
 }
 this.uploadDocList = tmp;
 }

 if(this.columnName === '音频'){
 if(isNaN(index) || index >= this.uploadAudioList.length){
 return false;
 }
 let tmp = [];
 for(let i = 0; i < this.uploadAudioList.length; i++){
 if(this.uploadAudioList[i] !== this.uploadAudioList[index]){
 tmp.push(this.uploadAudioList[i]);
 }
 }
 this.uploadAudioList = tmp;
 }

 if(this.columnName === '图片'){
 if(isNaN(index) || index >= this.uploadPicList.length){
 return false;
 }
 console.log('uuu')
 let tmp = [];
 for(let i = 0; i < this.uploadPicList.length; i++){
 if(this.uploadPicList[i] !== this.uploadPicList[index]){
 tmp.push(this.uploadPicList[i]);
 }
 }
 this.uploadPicList = tmp;
 }
 },
 doSubmit(){
 let params = {
 classify: this.tagId, // 针对视频资源时对应的分类id
 file: this.fileIdArr, // 选择完文件后,调用uploadFile这个接口,后端返回的数组
 resourceColumnId: JSON.parse(localStorage.getItem('columnId')), // 资源栏目id(视频、图片、音频、文档)
 title: this.uploadTitle // 上传时填写的标题
 };
 let columnName = localStorage.getItem('columnName')
 this.$api.post(addResources, params).then(res => {
 if(res.data.code === 1001){
 if(columnName === '视频'){
 this.$router.push({name: 'myVideo'});
 }else {
 this.$router.push({name: 'myResourceClassify'});
 }
 }
 }).catch(err => {
 console.log(err)
 })
 },
 },
 mounted(){
 this.getClassifyList();
 }
 }
</script>
<style lang="less" scoped>
 .upload{
 padding: 140px 36px 160px 36px;
 box-sizing: border-box;
 }

 .forPreview_video{
 position: relative;
 /*background: rgba(0,0,0,.7);*/
 video{
 width: 95%;
 max-height: 430px;
 }
 .delte{
 position: absolute;
 right: 0;
 bottom: 0;
 }
 }
 .forPreview_doc, .forPreview_audio{
 display: flex;
 margin-bottom: 10px;
 align-items: center;
 img{
 width: 56px;
 height: 56px;
 margin-right: 20px;
 }
 span:nth-of-type(1){
 flex: 1;
 }
 span:nth-of-type(2){
 margin-right: 20px;
 }
 }
 .forPreview_pic{
 display: flex;
 align-items: flex-end;
 img{
 width: 160px;
 height: 160px;
 }
 }

 .diy-detail{
 width: 100%;
 overflow: hidden;
 
 .btn{
 span{
 margin-bottom: 10px;
 }
 }
 .van-cell{
 background-color: #F0F0F0;
 border-radius: 35px;
 font-size: 26px;
 height: 69px;
 line-height: 69px;
 padding: 0 22px;
 color: #999;
 }
 .van-hairline--top-bottom::after, .van-hairline-unset--top-bottom::after {
 border-width: 0;
 }
 p{
 height: 64px;
 line-height: 64px;
 font-size: 32px;
 color: #333;
 position: relative;
 padding-left: 16px;
 }
 p::before{
 position: absolute;
 top: 0;
 left: 0;
 content: '*';
 color: #FF0000;
 }

 span{
 display: inline-block;
 width: 157px;
 background: #F0F0F0;
 border-radius: 35px;
 color: #999;
 font-size: 26px;
 padding: 14px 18px;
 margin-right: 28px;
 text-align: center;
 }
 .active{
 color: #fff;
 background: linear-gradient(to right,#FD5130,#FA6C34);
 }
 }
 .diy-submit {
 position: fixed;
 height: 150px;
 width: 90%;
 bottom: 0;
 background: #fff;

 .van-button {
 width: 100%;
 height: 90px;
 border-radius: 45px;
 font-size: 36px;
 color: #fff;
 background: linear-gradient(to right, #FD5130, #FA6C34);
 top: 50%;
 transform: translate(0, -50%);
 }
 .van-button--default {
 border: none;
 }
 }
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

vue 多文件上传 vue vantUI 文件上传 vue 文件上传