代码编织梦想

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

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

<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.全局注册直接

//上传图片
import UploadFile from '@/components/UploadImg'
Vue.component('UploadFile', UploadFile)

2.单页面使用

import UploadFile from "../../../components/UploadImg";
export default {
  name: "Post",
  components: { UploadFile },
}

页面如何使用

<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 = "";
      }
    }
  },

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_61869009/article/details/138978526

vue-element-admin的二次开发_坚持原创的博客-爱代码爱编程

最近也是完成了公司招聘管理系统后台的前端开发,项目已经开始测试了近期估计就会交付使用。一直是一个人在做,配合两个后端,说实话这种从很多不会到一个个独立debug解决问题到最后终于完成项目的感觉真的太有成就感了,看了一下项目开

微服务[学成在线] day13:使用FFmpeg进行格式转换以及m3u8文件生成、文件分块上传接口实现-爱代码爱编程

😎 知识点概览 为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。 本章节为【学成在线】项目的 day13 的内容 FFmpeg 的基本使用 使用 m3u8 和 video.js技术实现视频的在线播放 搭建媒资服务工程实现文件的分

vue+element 二次组件封装:表单、列表、下拉树、弹出选择、折叠卡片等(持续更新npm依赖)-爱代码爱编程

基于vue+element开发前端时,封装的一些组件,持续更新npm依赖,不喜勿喷 安装 npm地址 npm i vue-zeary-ctrl import vueZearyCtrl from "vue-zeary-ctrl"; //参数有{lang:'zh'} Vue.use(vueZearyCtrl); 全局扩展方法 //全局加载层

Element ui 组件库 使用技巧。-爱代码爱编程

el-radio组件 单选框取消选中。 el-radio 单选框组件默认是不能取消选中的. 解决办法: 我们可以给他添加 click事件,把 label 值 传入点击事件,然后每次点击的时候去判断 label 和 radio 的值是否相同.如果相同 就置为空,如果不同,就给 radio 赋值. 参考文章@官尔 方法一: <e

图片上传组件的封装_周亚鑫的博客-爱代码爱编程

效果 1.图片上传组件 <template> <div style="display: inline-block;margin-bottom: 24px;position: relative"&

day10-爱代码爱编程

补充:celery 1 课程详情接口 2 所有章节接口 3 课程列表前台 4 课程详情前台 5 视频托管 6 Header.vue搜索form 6.1 搜索后台接口 7 搜索功能前端 8 支付宝支付介绍 补充:cele

uview组件使用笔记-爱代码爱编程

图标样式 修改图标的样式 通过color参数修改图标的颜色通过size参数修改图标的大小,单位为rpx 效果图 <u-icon name="photo" color="#2979ff" size="28"></u-icon> 图片图标 1.3.0 这里说的图片图标,指的是小图标,起作用定位为"icon"图标作用

springboot交友app项目实战(详细介绍+案例源码) -爱代码爱编程

有人相爱,有人跳海 系列文章目录 1. 项目介绍及环境配置 2. 短信验证码登录 3. 用户信息 4. MongoDB 5. 推荐好友列表/MongoDB集群/动态发布与查看 6. 圈子动态/圈子互动

前端vue架构-爱代码爱编程

1 理解: 创建视图的函数(render)和数据之间的关联; 当数据发生变化的时候,希望render重新执行; 监听数据的读取和修改; defineProperty:监听范围比较窄,只能通过属性描述符去监听已

vue.js的发展史(一)-爱代码爱编程

Vue.js的发展史(一) 什么是Vue? Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。  来源官方解释--

vue3选项式和组合式生命周期说明-爱代码爱编程

生命周期:composition 生命周期先后顺序为: setup -beforeCreate和created的统称,只在composition里面取消这两个,可以在这里进行数据请求 onBeforeMount-挂载前,可以请求后台数据 onMounted-挂载,可以获取DOM实例 onBeforeUpdate-更新前,可以在此更改数据 onU

vue中的事件-爱代码爱编程

vue中的事件是什么 绑定事件用v-on,简写@v-on指令的参数是事件名(原生或者自定义),值是事件处理器有原生事件(click)和自定义事件(myEvent)在组件上使用原生事件,需要加native修饰符 自定义