如何实现图片上传预览?教你图片上传组件的封装(el-upload)

lxf2023-02-17 01:52:51

持续创作,加速成长!这是我参与「AdminJS日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

1.使用element-ui中的el-upload

这是element-ui自带的上传文件组件,可以通过通过点击或者拖拽上传文件

官网链接

这里我需要的是头像上传预览,所以我选择用户头像上传的el-upload代码

<el-upload
  class="avatar-uploader"
  action="https://jsonplaceholder.typicode.com/posts/"
  :show-file-list="false"
  :on-success="handleAvatarSuccess"
  :before-upload="beforeAvatarUpload">
  <img v-if="imageUrl" :src="imageUrl" class="avatar">
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

如何实现图片上传预览?教你图片上传组件的封装(el-upload)

2.封装组件

新建组件src/components/UploadImg/index.vue

  • 这里限制上传的图片一定为jpg格式:

const isJPG = file.type === 'image/jpeg';

  • 限制图片大小小于2MB

const isLt2M = file.size / 1024 / 1024 < 2;

  • URL.createObjectURL()可以把二进制文件转为一个Blob对象,然后img的src可以把blob地址解析显示图片

this.imageUrl = URL.createObjectURL(file.raw);

<el-upload
  class="avatar-uploader"
  action="https://jsonplaceholder.typicode.com/posts/"
  :show-file-list="false"
  :on-success="handleAvatarSuccess"
  :before-upload="beforeAvatarUpload">
  <img v-if="imageUrl" :src="imageUrl" class="avatar">
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

<style>
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>

<script>
  export default {
    data() {
      return {
        imageUrl: ''
      };
    },
    methods: {
      handleAvatarSuccess(res, file) {
        this.imageUrl = URL.createObjectURL(file.raw);
      },
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg';
        const isLt2M = file.size / 1024 / 1024 < 2;

        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG 格式!');
        }
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
        }
        return isJPG && isLt2M;
      }
    }
  }
</script>

3.注册公共组件

  • 如果上传图片组件使用的很多,可以把该组件注册为全局组件
// 全局注册组件
import UploadImg from '@/components/UploadImg'
export default {
  install(Vue) {
    Vue.component('UploadImg', UploadImg)
  }
}
  • 如果使用的较少可以作为局部组件使用
  • 每次使用是导入父组件并注册为组件即可

4.页面中使用组件

  • 因为注册了公共组件,所以不需要在引入组件,直接写标签即可使用组件
    <!-- 员工照片 -->
      <el-form-item label="员工头像">
        <!-- 放置上传图片 -->
        <UploadImg />
        <img>
      </el-form-item>

5.使用腾讯云服务器来实现图片存储

前置基础:

1.在云服务器上的准备:申请cos服务器,配置密钥,设置cors访问console.cloud.tencent.com/cos

2.在代码层面的准备:

(1) 下载一个官方提供的操作cos服务的包(cos-js-sdk-v5)

   (2) 用自己的密钥去实例化cos

   (3) 具体做上传

项目中安装依赖

npm i cos-js-sdk-v5 --save

实例化cos对象

src/components/UploadImg中实例化Cos对象,传入身份id和key

注意:这是前端中的测试写法,实际不可以把身份密钥暴露在前端代码中

// 下面的代码是固定写法
const COS = require('cos-js-sdk-v5')
// 填写自己腾讯云cos中的key和id (密钥)
const cos = new COS({
  SecretId: 'xxx', // 身份识别ID
  SecretKey: 'xxx' // 身份密钥
})
  • 在腾讯云中找到id和秘钥

  • 上边用到的SecretId和SecretKey在这里找到:

如何实现图片上传预览?教你图片上传组件的封装(el-upload)

使用cos对象完成上传

给el-upload注册http-request事件

  • 把原来的action路径改为#
  • http-request事件用于覆盖默认的上传行为,可以自定义上传的实现
  <el-upload
    class="avatar-uploader"
    action="#"
    :http-request="upload"
    :show-file-list="false"
    :on-success="handleAvatarSuccess"
    :before-upload="beforeAvatarUpload"
  >
    <img v-if="imageUrl" :src="imageUrl" class="avatar">
    <i v-else class="el-icon-plus avatar-uploader-icon" />
  </el-upload>

上传事件

upload(res) {
  if (res.file) {
    // 执行上传操作
    cos.putObject({
      Bucket: 'xxxxxx', /* 存储桶 */
      Region: 'xxxx', /* 存储桶所在地域,必须字段 */
      Key: res.file.name, /* 文件名 */
      StorageClass: 'STANDARD', // 上传模式, 标准模式
      Body: res.file // 上传文件对象
    }, (err, data) => {
      console.log(err || data)
      // 上传成功之后
      if (data.statusCode === 200) {
        this.imageUrl = `https:${data.Location}`
      }
    })
  }
}

上边的Bucket和Region在这里可以找到

如何实现图片上传预览?教你图片上传组件的封装(el-upload)

注意:这里不能使用function定义函数,要用箭头函数,因为this需要指向vue实例

如何实现图片上传预览?教你图片上传组件的封装(el-upload)

图片成功预览

如何实现图片上传预览?教你图片上传组件的封装(el-upload)