实现移动端图片上传,回显功能

背景:使用的vant 组件开发钉钉H5微应用,但是钉钉对vant 的图片是不兼容的,因此这个上传图片的组件,在手机上默认图片加载不出来,是一个灰色的框。

功能:要实现上传,展示,回显的功能

给input 的type属性设置成file属性,通过label来绑定这个input ,来获取到这个图片的file 对象

通过 new FileReader()  这个对象中的方法,来本地的解析这个选择的file对象

  FileReader.readAsDataURL()  方法, 开始读取指定的 Blob 中的内容。一旦完成,result 属性中将包含一个 data: URL 格式的 Base64 字符串以表示所读取文件的内容。可以获取到这个file对对象的本地base64 格式的内容,来实现图片的展示

通过发送请求,将这个file 对象发送到服务器,根据返回的地址进行处理,传到父组件使用

至于回显功能:由于使用了vant 组件 所以直接使用了一个遮罩层

上传组件

<template>
  <div style="position: relative" class="box">

    <div class="upload">
      <label for="file" class="custom-file-upload" v-if="flag">
        <div class="btn">点击上传图片</div>
      </label>
      <input
        @change="onchange"
        type="file"
        name=""
        id="file"
        accept="image/*"
        style="display: none"
      />

      <div class="preview">
        <van-image width="100" height="100" :src="src" @click="imgClick" />
        <span
          class="del"
          @click="delHandler"
          v-if="this.src != this.defaultImage && flag"
          >✖</span
        >
      </div>
    </div>

    <van-overlay :show="show" @click="overlayHandler">
      <div class="wrapper">
        <van-image :src="src" />
      </div>
    </van-overlay>
  </div>
</template>
<script>
import CryptoJS from "crypto-js";
import { Base64 } from "js-base64";
export default {
  props: {
    //回显的图片地址
    fileUrl: {
      type: String,
      default: () => "",
    },
  },
  data() {
    return {
      defaultImage:
        "https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png",//进行对比的图片
      src: "https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png",//进行渲染的图片
      show: false,
      file: null,
      tool: "",
      flag: true,
    };
  },
  methods: {
    onchange(e) {
      this.file = e.target.files[0];
    //  定一个一个formdata 对象
      let formData = new FormData();
      formData.append("file", this.file);
      formData.append("insert", JSON.stringify({}));
      // 向存储图片的服务器发送请求
      R.Ding.uploadFile("?resignation", formData).then((res) => {
        if (res.status == 200) {
          // 替换返回字符串的格式
          let aaa = res.data.replaceAll("\\", "/");
          aaa = aaa.substring(3, aaa.length);
         
          let url = `域名${aaa}`;
         
          //  将服务器返回的地址传递回去
          this.$emit("href", url);
        }
      });
      // 读取出来这个文件
      // 创建一个FileReader 对象
      const reader = new FileReader();
      // 可以将file 文件解析成一个base64
      reader.readAsDataURL(this.file);
      //   这里是异步的`
      reader.onload = (e) => {
        //   把数据读出来生成一个本地DataURL
        // 读取出来的文件赋值给img 实现本地预览
        this.src = e.target.result;
      };
    },
    // 删除图片
    delHandler() {
      this.src = this.defaultImage;
      this.file = null;
      this.$emit("href", null);
    },
    //点击图片
    imgClick() {
      if (this.src == this.defaultImage) {
        return;
      } else {
        this.show = true;
      }
    },
    // 点击遮罩层
    overlayHandler() {
      this.show = false;
      console.log(1111);
    },
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {
    //图片回显
    this.$nextTick(() => {
      if (this.fileUrl != "") {
        this.src = this.fileUrl;
        this.flag = false;
      }
    });
  },
};
</script>
<style scoped>
.box {
}

.upload {
  display: flex;
  flex-direction: column;
}

.show {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #000;
  /* opacity: .8; */
}

.show_img {
}

.preview {
  position: relative;
  width: 100px;
  height: 100px;
  overflow: hidden;
  /* 添加这一行 */
}

.del {
  cursor: pointer;
  font-size: 12 px;
  text-align: center;
  line-height: 25px;
  color: #fff;
  position: absolute;
  width: 25px;
  height: 25px;
  background-color: #000;
  border-radius: 50%;
  right: -5px;
  top: -5px;
}

.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.btn {
  color: #fff;
  background-color: #1989fa;
  width: 110px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  border-radius: 5px;
  margin: 10px 0;
  font-size: 15px;
}
</style>

父组件使用

在子组件上自定义一个事件,来获取传递过来的地址

 
<div class="fieldBox">
      <div class="fieldTit"><span class="star">*</span>工号报删凭证:</div>
      <div class="upload">

        <Upload :fileUrl="fileUrl" @href="loadHandler"></Upload>
                
      </div>
    </div>

// js 
// 封装upload返回的图片地址
    loadHandler (url) {
      this.dataObj.fileFrom = url;
      console.log(url)
    },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值