封装上传图片组件

504 阅读1分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路

一.在按钮区域中,新增 <input type="file" /> 文件选择框

思路梳理:

  • 利用input的的change事件实现上传图片
  • 按钮利用ref触发input的change事件
  • 利用是否获取到图片来控制上传按钮的显示和隐藏
      <div class="btn-box">
        <input @change="changeFile" accept="image/*"
         ref="inp" style="display:none" type="file">
        <el-button type="primary" icon="el-icon-plus"
         @click="$refs.inp.click()">选择图片</el-button>
        <el-button @click="upload" type="success"
         icon="el-icon-upload" :disabled="!avatar">上传头像</el-button>
      </div>

想了解accept="image/"的可以参考juejin.cn/post/707816…

二.图片,用来展示用户选择的头像

      <img v-if="avatar" :src="avatar" alt="" class="preview" />
      <img v-else src="../../../assets/images/avatar.jpg" alt="" class="preview" />

三.changeFile事件实现上传

  data () {
    return {
      avatar: ''
    }
  },
  ...
  changeFile (e) {
      // img标签的src属性只能设置两种值
      // url和base64 (Data URL)
      // 立方体方法
      // readAs读成
      // fr.readAsArrayBuffer读文件
      // fr.readAsArrayBuffer二进制
      // fr.readAsDataURL baseURL
      const files = e.target.files
      if (files.length > 0) {
        // 创建FileReader对象
        const fr = new FileReader()
        // 读取文件转成BASE64
        fr.readAsDataURL(files[0])
        // (method) FileReader.readAsDataURL(blob: Blob): void
        // 通过读取父类获得子类
        // blob 子类对象
        // Blob 父类对象
        // void 没有返回值
        // 监听事件,得到结果
        // 必须使用箭头函数,因为e要指向外部
        fr.onload = (e) => {
          this.avatar = e.target.result
        }
      } else {
        this.avatar = ''
      }
    },

四.点击上传发送请求

    async  upload () {
      const { data: res } = await this.$http.patch('更改用户信息图片接口', { avatar: this.avatar })// 以对象形式传递
      if (res.code !== 0) return this.$message.error(res.message)//简单提示信息
      this.$message.success(res.message)
      this.$store.dispatch(获取用户信息方法)//重新获取用户信息
    }

五.效果展示

初步渲染

image.png

点击选择

image.png

点击上传

image.png

实现上传

image.png