Vue开发遇坑记--upload上传图片

778 阅读1分钟

需求:想要上传图片后 同时给预览的图片生成一个名字+单选框,同时图片名字要求点击可以编写 👇

image.png

思路一、使用el-upload

首先生成的图片加字就卡住了,找到了file的作用于插槽拿到了files,标题和单选框都添加好了。

但点击名字的时候所有input都响应了...并且blur事件离开的时候视图上的名字变了 ,但是赋值给data里的数据时名字并没有改变...

image.png

思路二、迂回作战:改用原生input

            <input type="file" accept=".png,.jpg,.jpeg" ref="IMGupload" v-show="false"
              @change='handleChange' />
            <div class="uploadLeft" @click='triggerIMGupload'>
              <span class="el-icon-plus"> </span>
              <span>单次上传<br>最多10张图片</span>
            </div>

            <ul class="previeShow">
              <li v-for="(item,index) in IMGlist" :key="index">
                <img :src="item.imgsrc" alt="">
              </li>
            </ul>

1. 单次图片上传

let files = this.$refs.IMGupload.value 拿到路径,但是转blob地址时报错

✅ 换成拿fileslet files = this.$refs.IMGupload.files 转blob地址成功,单个图片生成成功

总结:

  • 通过input实例.files 拿到图片地址 --值为数组
  • 通过window.URL.createObjectURL(files[0]) 来把图片地址转换成blob地址

2. 连续多次上传图片

多次上传change未触发

❓ 第一次上传,触发change拿到了files,但是第二次再点击上传 change未被触发

✅ 把value清空 this.$refs.IMGupload.value = '' 当input+file类型的时候 只有当value变化才会触发change

第二次上传 数据重复

❓ 第一次传了一张,显示成功 第二次传了1张,但是此时图片预览突然从1张变成了3张

image.png

✅ 拿到的files是最新上传的files文件,若有重复去查看push的时候是否重复推入

总结:

  • input+file类型 必须input实例的value变化才会触发change事件
  • 如果多次上传拿到的files是最新的那一次files文件!

触发单个input

❓点击拿到当前li的index 修改showWords的true/false 会把所有的index一起触发

✅ 所以标题的v-if的控制条件变为 v-if="showWords!==index" ,默认值给null,点击标题的时候把当前index给showWords,这样v-if就为false就会隐藏文字 改为输入框,input blur的时候把showWords的值再改为null,这样就触发了v-if为true显示改之后的标题~

不过 应该有更简洁的方法吧? 请赐教 🙏

完整代码如下:

              <ul class="previeShow">
                <li v-for="(item,index) in formData.optionList" :key="index">
                  <div class="imgWrap">
                    <img :src="item.optionContent" alt="">
                    <p @click="handleDel(index)">删除</p>
                  </div>
                  <div class="discribe">
                    <input type="radio" :checked="true" class="singleChoose" />
                    <span v-if="showWords!==index" class=" Imgwords"
                      @click="changeIMGName(index)">{{item.optionInfo}}</span>
                    <el-input v-else type="text" v-model="item.optionInfo" @blur="changedOk" />
                  </div>
                </li>
                <li v-show="IMGlist.length>=10 ? false :true">
                  <input type="file" accept=".png,.jpg,.jpeg" ref="IMGupload" v-show="false"
                    @change='handleChange' />
                  <div class="uploadLeft" @click='triggerIMGupload'>
                    <span class="el-icon-plus"> </span>
                    <span>单次上传<br>最多10张图片</span>
                  </div>
                </li>
              </ul>
    handleChange () {
      let files = this.$refs.IMGupload.files; //最近一次上传的文档
      this.formData.optionList.push(
          { optionContent: window.URL.createObjectURL(files[0]), 
            optionInfo: `图片` 
          })
      this.$refs.IMGupload.value = ''; //这个value变化,change才会触发
      //(是file缓存的问题 input+file 他判断你value没有变化 就不会触发change)
    },