vue+elementUI同时上传视频和图片并回显

这是一个关于Vue组件的实现,用于智能识别图片和视频类型并进行上传。组件通过检查文件名的后缀来判断是图片还是视频,并分别使用`<video>`标签和`<el-image>`组件展示。同时,它支持上传限制、预览功能和删除操作。在父组件中,组件被用来展示和管理一组图片和视频。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.效果
在这里插入图片描述
2.数据结构;根据name或url后缀来判断是图片或者视频类型

fileList = [
          {name:'123.mp4',url:'123.mp4'},
          {name:'124.png',url:'https://img0.baidu.com/it/u=1942253063,3807598283&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'},
          {name:'hahagwe.png',url:'https://img0.baidu.com/it/u=1040225459,210273596&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400'},
        ]

3.判断是否是图片或者视频的方法

  //图片视频匹配
      matchType(name){
        //后缀获取
        let suffic = '';
        //获取类型结果
        let result = '';
        try {
          let fileArr = name.split('.');
          suffic = fileArr[fileArr.length - 1]
          // console.log('suffic',suffic);
        } catch (error) {
            suffic = ''
        }
        //图片格式
        var imgList = ['png','jpg','jpeg','bmp','gif'];
        //进行图片匹配
        result = imgList.some(item=>{
          return item === suffic
        })
        // console.log('结果',result);
        if(result){
          result = 'image';
          // console.log('结果',result);
          return result
        }
      },

4.全部代码展示—>子组件

<template>
  <div style="display: inline-flex;">
    <div class="img-list-item common mb_10" v-for="(item,index) in fileList" :key="index">
      <video v-if="!(matchType(item.name))" :style="{width:w,height:h,margin:'0 9px'}"  controls="controls" :src="item.url"> 您的浏览器不支持视频播放</video>
      <el-image
      v-if="matchType(item.name)"
           @mouseover="srcList = [item.url]"
           :preview-src-list="srcList"
            :style="{width:w,height:h,margin:'0 9px'}"
            :src="item.url"
            fit="cover"></el-image>
      <i class="del-img" @click="forkImage(index)"  v-if='isShowImg==true'></i>
    </div>
    <div v-if="maxlength<limit" @click="change">
    <el-upload action="https://hrm-oss-dbg.oss-cn-chengdu.aliyuncs.com"
               :data="dataObj" :show-file-list="false"
               :auto-upload="true"
               :on-remove="handleRemove"
               :on-success="handleUploadSuccess"
               :before-upload="beforeUpload"
               :on-progress="uploadVideoProcess">
      <span class="warpss" :style="{width:w,height:h,lineHeight:h}"  v-if='isShowImg==true'>
        <i v-else class="el-icon-plus" :style="{color:'#8C939D',fontSize: '18px',fontWeight:'bold',padding:paddings}"></i>
      </span>
    </el-upload>
    </div>
  </div>
</template>
<script>
  import {
    policy1
  } from '@/api/oss'//oss上传接口
  export default {
    props: {
      //是否需要上传图片(false:需要,true:不需要,只能查看图片不能做任何操作)
			isShowImg: {
				type: Boolean,
				default: false
			},
      //个数显示
      limit:{
        type:Number,
        default: 5
      },
      maxlength:{
        type:Number
      },
      value: Array,
      //最大上传图片数量
      maxCount: {
        type: Number,
        default: 5
      },
      //宽度
      w: {
        type: String,
        // default:'100px'
      },
      //高度
      h: {
        type: String,
        // default:'100px'
      },
      paddings: {
        type: String,
      }
    },
    data: function() {
      return {
        srcList:[],
        videoFlag: false,
        isShow:true,
        videoUploadPercent: 0,
        count:5,
        videis: false,
        dataObj: {
          policy: '',
          signature: '',
          key: '',
          ossaccessKeyId: '',
          dir: '',
          host: ''
        },
        dialogVisible: false,
        dialogImageUrl: []
      }
    },
    computed: {
      fileList() {
           this.$emit('videoData23',this.value);
            return this.value;
      }
    },
    mounted() {
      if(this.fileList.length<this.limit){
         this.isShow = true;
      }else{
        this.isShow = false;
      }
    },
    methods: {
      //图片视频匹配
      matchType(name){
        //后缀获取
        let suffic = '';
        //获取类型结果
        let result = '';
        try {
          let fileArr = name.split('.');
          suffic = fileArr[fileArr.length - 1]
          // console.log('suffic',suffic);
        } catch (error) {
            suffic = ''
        }
        //图片格式
        var imgList = ['png','jpg','jpeg','bmp','gif'];
        //进行图片匹配
        result = imgList.some(item=>{
          return item === suffic
        })
        // console.log('结果',result);
        if(result){
          result = 'image';
          // console.log('结果',result);
          return result
        }
      },
      //删除视频/图片
      forkImage(index) {
        var data = this.fileList.splice(index, 1);
        this.$emit("delFile", this.fileList);
        if(this.fileList.length<this.limit){
           this.isShow = true;
        }else{
          this.isShow = false;
        }
      },
      change(){
        // console.log('点',this.fileList)
        if(this.fileList.length<this.limit){
           this.isShow = true;
        }else{
          this.isShow = false;
        }
      },
      getUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
          return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
        })
      },
      emitInput(fileList) {
        let value = [];
        for (let i = 0; i < fileList.length; i++) {
          value.push(fileList[i].url);
        }
        this.$emit('input', value)
      },
      handleRemove(file, fileList) {
        this.emitInput(fileList)
      },
      //上传图片/视频成功后的操作
      handleUploadSuccess(res, file) {
        console.log("成功后", file)
        let url = this.dataObj.host + '/' + this.dataObj.key.replace('${filename}', file.name);
        this.fileList.push({
          name: file.name,
          url: url
        });
        this.emitInput(this.fileList);
        this.dialogVisible = true;
        this.videoUploadPercent = 0;
        if(this.fileList.length<this.limit){
           this.isShow = true;
        }else{
          this.isShow = false;
          this.$message({
            message: '最多只能上传' + this.limit + '个视频/张图片',
            type: 'warning',
            duration: 1000
          });
        }
      },
      //进度条
      uploadVideoProcess(event, file, fileList) {
        // this.videoFlag = true;
        this.videoUploadPercent = Math.floor(event.percent);
      },
      beforeUpload(file) {
        // this.videoFlag = true;
        //视频/图片校验
         if (['video/mp4', 'video/ogg', 'video/flv','video/avi','video/wmv','video/rmvb','image/jpeg','image/PNG','image/gif'].indexOf(file.type) == -1) {
                this.$message.error('请上传正确的视频/图片格式');
                return false;
            }
            //以下为oss上传接口
        // const _self = this;
        // return new Promise((resolve, reject) => {
        //   policy1().then(response => {
        //     _self.dataObj.policy = response.data.policy;
        //     _self.dataObj.signature = response.data.signature;
        //     _self.dataObj.ossaccessKeyId = response.data.accessid;
        //     _self.dataObj.key = response.data.dir + this.getUUID() + '_${filename}';
        //     _self.dataObj.dir = response.data.dir;
        //     _self.dataObj.host = response.data.host;
        //     // _self.dataObj.callback = response.data.callback;
        //     resolve(true)
        //   }).catch(err => {
        //     console.log(err)
        //     reject(false)
        //   })
        // })
      },
    }
  }
</script>
<style lang="scss" scoped>
  .warpss {
    display: inline-block;
    border: 1px dashed #DEE5ED;
  }

  ::v-deep.el-upload-list {
    display: none;
  }

  .el-upload-video {
    width: 149px;
    height: 149px;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .el-upload-video-i {
    font-size: 20px;
    font-weight: bold;
    padding-top: 43px;
    color: #8c939d;
    width: 50px;
    height: 50px;
    line-height: 50px;
    text-align: center;
  }

  //视频
  .img-list-item {
    position: relative;
    margin: auto;
  }



  .img-list-item i.del-img {
    width: 20px;
    height: 20px;
    display: inline-block;
    background: rgba(0, 0, 0, .6);
    background-image: url(../assets/images/close.png);
    background-size: 18px;
    background-repeat: no-repeat;
    background-position: 50%;
    position: absolute;
    top: 0;
    right: 9px;
  }
</style>

5.父组件(记得在父组件里面引入并注册子组件哦,在这就写了哈,各位宝儿~)

<template>
  <div class="app-container">
<upload-img :isShowImg="isShowImg" :maxlength="slider_image.length" :limit="5" w="150px" h="150px" v-model="slider_image"></upload-img>
</div>
</template>
<script>
export default {
    data(){
    return{
      slider_image:[
          {name:'123.mp4',url:'123.mp4'},
          {name:'124.png',url:'https://img0.baidu.com/it/u=1942253063,3807598283&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'},
          {name:'hahagwe.png',url:'https://img0.baidu.com/it/u=1040225459,210273596&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400'},
        ]
    },
    methods:{
    }
}
</script>
### Vue ElementUI 实现多图片上传回显 为了实现多图片上传及其回显的功能,在前端部分可以利用 `element-ui` 提供的 `<el-upload>` 组件。该组件支持多种配置选项,能够很好地适应不同场景下的需求。 #### 属性设置 几个重要的属性对于控制文件的选择展示至关重要: - **action**: 设置上传接口地址。 - **list-type**: 使用 `"picture-card"` 来创建照片墙样式的列表[^1]。 - **auto-upload**: 默认情况下设为 `false` 以便于手动触发上传操作。 - **on-preview**, **on-remove** 及其他事件处理函数用于自定义交互逻辑,比如预览已选文件或移除某项前执行特定动作。 - **http-request**: 自定义上传请求行为,当需要对接特殊的服务器端API时非常有用[^4]。 - **file-list**: 初始文件列表,可用于页面加载完成后填充已有资源的数据以达到回显的效果[^3]。 下面给出一段简单的HTML模板代码片段作为例子说明如何构建一个多图片上传区域,且能够在选择新图片之后立即显示出缩略图形式的预览;同时也展示了怎样通过编程方式调用上传过程而不是依赖默认的行为。 ```html <template> <div id="app"> <!-- 图片上传 --> <el-upload action="#" list-type="picture-card" :auto-upload="false" :on-change="handleChange" :before-upload="handleBeforeUpload" :on-remove="handleRemove" :file-list="imageList" multiple > <i slot="default" class="el-icon-plus"></i> <div slot="file" slot-scope="{ file }"> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span @click="handlePictureCardPreview(file)"> <i class="el-icon-zoom-in"></i> </span> <span @click="handleDownload(file)"> <i class="el-icon-download"></i> </span> <span @click="handleRemove(file)"> <i class="el-icon-delete"></i> </span> </span> </div> </el-upload> <!-- 对话框显示大图 --> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt="" /> </el-dialog> <!-- 手动上传按钮 --> <el-button type="primary" @click="submitUpload">上传</el-button> </div> </template> ``` 接着是对应的JavaScript/TypeScript脚本部分,这里假设使用Vue CLI 创建的应用程序结构: ```javascript <script> export default { data() { return { imageList: [], // 存储当前选定的图片信息对象数组 dialogImageUrl: '', // 当前被点击查看的大图链接 dialogVisible: false, // 控制对话框可见性的布尔变量 }; }, methods: { handleChange(file, fileList) { this.imageList = fileList; }, handleBeforeUpload(file) { const isJPGOrPNG = ['image/jpeg', 'image/png'].indexOf(file.type) !== -1; if (!isJPGOrPNG) { this.$message.error('仅限jpg/png格式!'); } const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { this.$message.error('图片大小不超过2MB!'); } return isJPGOrPNG && isLt2M; }, handleRemove(file) { console.log(`删除${file.name}`); }, handlePictureCardPreview(file) { this.dialogImageUrl = file.url; this.dialogVisible = true; }, handleDownload(file) { window.open(file.url); }, submitUpload() { let formData = new FormData(); for (let i = 0; i < this.imageList.length; i++) { formData.append("files", this.imageList[i].raw); // 将原始File对象加入到FormData中 } fetch('/api/upload', { method: "POST", body: formData }) .then((response) => response.json()) .then((result) => { console.log(result.message); }); } } }; </script> ``` 这段代码实现了基本的多图片选择、本地预览以及批量上传至指定URL的功能。实际项目开发过程中可能还需要考虑更多细节问题,例如错误提示优化、进度条显示等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值