el-upload上传图片,视频可获取视频时长。

对element-ui组件的upload组件再一次封装,简单记录。下面是效果图。

注意点:该组件现在仅支持单图和单个视频上传。

javascript 复制代码
<template>
  <div :style="myStyle">
    <div
      class="uploads"
      :style="{
        width: upWith + 'px',
        height: upHeight + 'px',
        borderRadius: upBradius + 'px',
      }"
    >
      <div v-if="pathUrl" class="isblock">
        <div v-show="utype == 1">
          <el-image
            ref="preview"
            :style="{
              width: upWith + 'px',
              height: upHeight + 'px',
              borderRadius: upBradius + 'px',
            }"
            :preview-src-list="[pathUrl]"
            :src="pathUrl"
          ></el-image>
          <div class="imgs_prews">
            <div
              class="imgs_prew"
              :style="{
                width: upWith + 'px',
                height: upHeight + 'px',
                borderRadius: upBradius + 'px',
              }"
            >
              <i @click="ylimg()" class="el-icon-view"></i>
              <span></span>
              <i @click="deleteimg()" class="el-icon-delete"></i>
            </div>
          </div>
        </div>
        <div v-show="utype == 2" style="display: flex">
          <div style="position: relative">
            <video
              :style="{
                width: upWith + 'px',
                height: upHeight + 'px',
                borderRadius: upBradius + 'px',
              }"
              :src="pathUrl"
              controls
              preload="auto"
              playsinline="true"
            ></video>
          </div>
          <div style="position: absolute; right: 0px">
            <el-button @click="deleteimg()" size="mini">重新上传</el-button>
          </div>
        </div>
      </div>
      <el-upload
        v-else
        class="avatar-uploader"
        :style="{
          width: upWith + 'px',
          height: upHeight + 'px',
          borderRadius: upBradius + 'px',
          lineHeight: upHeight + 'px',
        }"
        :action="updatehttp"
        :headers="headers"
        :data="updataimg"
        accept=".jpg, .jpeg, .png, .gif, .bmp, .JPG, .JPEG, .PBG, .GIF, .BMP"
        :show-file-list="false"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
        :on-progress="topprogressicon"
      >
        <div v-show="isopens">
          <i class="el-icon-loading"></i>
          上传中...
        </div>
        <i v-show="!isopens" class="el-icon-plus avatar-uploader-icon-sf">{{
          uptext
        }}</i>
      </el-upload>
    </div>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";
export default {
  props: {
    //改变文字
    uptext: {
      type: String,
      default: "上传图片",
    },
    upWith: {
      type: Number,
      default: 100,
    },
    upHeight: {
      type: Number,
      default: 100,
    },
    upBradius: {
      type: Number,
      default: 16,
    },
    upimgUrl: {
      type: String,
    },
    //1图片 2视频
    utype: {
      type: Number,
      default: 1,
    },
  },
  computed: {
    myStyle() {
      return {
        "--upWith": this.upWith + "px",
        "--upHeight": this.upHeight + "px",
        "--upBradius": this.upBradius + "px",
      };
    },
  },
  data() {
    return {
      updatehttp: '', //上传的接口
      headers: {
        Authorization: "Bearer " + getToken(), //自己的token
      },
      updataimg: {
        fileKey: "", //上传时携带参数
      },
      isopens: false, //上传加载图
      isok: false, //上传成功失败,
      dataFile: {
        path: "",
        videoTime: "",
      },
      pathUrl: "",
    };
  },
  watch: {
    upimgUrl: {
      handler(val) {
        if (val) {
          this.pathUrl = val;
        } else {
          this.pathUrl = "";
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    getTimes(file) {
      var content = file;
      //获取上传视频时长
      var url = URL.createObjectURL(content);
      var audioElement = new Audio(url);
      audioElement.addEventListener("loadedmetadata", (_event) => {
        this.dataFile.videoTime = parseInt(audioElement.duration);
      });
    },
    //上传成功
    handleAvatarSuccess(res, file) {
      if (this.isok) {
        this.dataFile.path = res.url;
        this.pathUrl = res.url;
        this.isopens = false;
        this.$emit("changeName", this.dataFile);
      }
    },
    //文件上传时
    topprogressicon(event, file, fileList) {
      if (this.isok) {
        this.isopens = true;
      }
    },
    //上传之前的操作
    beforeAvatarUpload(file) {
      if (this.utype == 1 && file.type.includes("image")) {
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isLt2M) {
          this.$message.error("上传图片大小不能超过 2MB!");
          this.isok = false;
        } else {
          this.isok = true;
        }
      }else if (this.utype == 2 && file.type.includes("video")) {
        this.getTimes(file);
        const isLt2M = file.size / 1024 / 1024 < 500;
        if (!isLt2M) {
          this.$message.error("上传视频大小不能超过 500MB!");
          this.isok = false;
        } else {
          this.isok = true;
        }
      } else {
        this.$message.error("上传类型错误!");
        this.isok = false;
      }
    },
    //删除
    deleteimg() {
      this.pathUrl = "";
      this.$emit("changeName", "");
    },
    //预览
    ylimg() {
      this.$refs.preview.clickHandler();
    },
  },
};
</script>

<style scoped>
.uploads {
  position: relative;
}

.avatar-uploader /deep/ .el-upload {
  width: var(--upWith);
  height: var(--upHeight);
  border-radius: var(--upBradius);
}

.avatar-uploader-icon-sf {
  color: #999999;
}

.avatar-uploader {
  border: 1px dashed #d9d9d9;
  width: 100%;
  text-align: center;
}

.isblock {
  width: 100%;
}

.isblock:hover .imgs_prews {
  display: block;
}

.imgs_prews {
  display: none;
}

.imgs_prew {
  position: absolute;
  top: 0;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
}

/* 左右图标 */
.imgs_prew i {
  display: inline-block;
  font-size: 20px;
  cursor: pointer;
}

.imgs_prew span {
  width: 2px;
  height: 18px;
  margin: 0px 20px;
  background-color: #fff;
}
</style>

组件注册两种方法。

1.全局注册直接

javascript 复制代码
//上传图片
import UploadFile from '@/components/UploadImg'
Vue.component('UploadFile', UploadFile)

2.单页面使用

javascript 复制代码
import UploadFile from "../../../components/UploadImg";
export default {
  name: "Post",
  components: { UploadFile },
}

页面如何使用

javascript 复制代码
<template>
  <div>
      //注意上传视频要修改utype为2
      <UploadFile
        :utype='1'
        :up-with="140"  
        :upimgUrl="form.companyHead"
        :up-height="160"
        :up-bradius="10"
        uptext="请上传封面图"
        @changeName="changUrl"
      ></UploadFile>
  </div>
</template>

  methods: {
    changUrl(e){
      //e.videoTime 获取到视频的时长
      if (e) {
        this.form.companyVideo = e.path;
      } else {
        this.form.companyVideo = "";
      }
    }
  },
相关推荐
类人_猿35 分钟前
ASP.NET Web(.Net Framework) Http服务器搭建以及IIS站点发布
前端·iis·asp.net·.net·http站点服务器
组态软件4 小时前
web组态软件
前端·后端·物联网·编辑器·html
前端Hardy4 小时前
HTML&CSS:MacBook Air 3D 动画跃然屏上
前端·javascript·css·3d·html
汪小白JIY5 小时前
【VUE3】VUE组合式(响应式)API常见语法
vue.js·vue3·语法
loey_ln5 小时前
观察者模式和发布订阅模式
javascript·观察者模式·react.js
cnsxjean7 小时前
SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传
java·前端·spring boot·分布式·后端·中间件·架构
ZL_5677 小时前
uniapp中使用uni-forms实现表单管理,验证表单
前端·javascript·uni-app
沉浮yu大海7 小时前
Vue.js 组件开发:构建可重用且高效的 UI 块
前端·vue.js·ui
代码欢乐豆7 小时前
软件工程第13章小测
服务器·前端·数据库·软件工程
sunly_7 小时前
Flutter:启动屏逻辑处理02:启动页
android·javascript·flutter