vue圖片上傳际跪,預(yù)覽商佛,壓縮組件

代碼還在優(yōu)化,后續(xù)會進(jìn)行更新姆打,該組件引用了element-ui的彈出框樣式良姆,使用axios庫進(jìn)行ajax請求,向后臺發(fā)送的參數(shù)是formData對象幔戏,如果需要的base64可不轉(zhuǎn)formData對象玛追,直接將壓縮過后的base64發(fā)給后臺

該組件上傳圖片的大致思路:
  1. 利用H5的FileReader對象將上傳的圖片轉(zhuǎn)成base64格式
  2. 利用canvas的drawImage方法重繪上傳的圖片(注:drawimage是一個異步方法,需要在圖片讀取成功后在進(jìn)行重繪闲延,否則可能會壓縮不成功)
  3. 在利用canvas的toDataURL方法將圖片壓縮
  4. 在將壓縮后的base64編碼圖片轉(zhuǎn)成blob對象
  5. 創(chuàng)建一個formData對象痊剖,將blob對象append進(jìn)去
  6. 圖片上傳時需設(shè)置請求為 { "Content-Type": "multipart/form-data" }
  7. 將formData對象上傳到后臺

html部分

  <div class="upload">
    <!-- 圖片展示 -->
    <div class="cha" v-show="(imgUrl)">
      <!-- 刪除icon -->
      <div class="del"><i class="el-icon-delete" @click="delImg"></i></div>
      <img :src="imgUrl">
      <!-- 放大icon -->
      <div class="layer"><i @click="isEnlargeImage = true" class="el-icon-view"></i></div>
    </div>
    <!-- 圖片上傳控件 -->
    <div class="load" v-show="(!imgUrl)">
      <input type="file" name="" id="form" @change="uploadIMG">
    </div>

    <!-- 圖片預(yù)覽彈框 -->
    <el-dialog :visible.sync="isEnlargeImage" size="large"  :append-to-body="true" top="8%" width="60%">
            <img @click="isEnlargeImage = false" style="width:100%;" :src="imgUrl">
    </el-dialog>
    
  </div>

JS代碼

<script>
export default {
  props: ["uploadUrl"],
  data() {
    return {
      picavalue: "",
      imgUrl: null,
      isEnlargeImage: false
    };
  },
  methods: {
    uploadIMG(e) {
      let files = e.target.files || e.dataTransfer.files;
      if (!files.length) return;
      this.picavalue = files[0];
      console.log(this.picavalue.size / 1024);
      if (this.picavalue.size / 1024 > 5000) {
        this.$message({
          message: "圖片過大不支持上傳",
          type: "warning"
        });
      } else {
        this.imgPreview(this.picavalue);
      }
    },
    //獲取圖片
    imgPreview(file, callback) {
      let self = this;
      //判斷支不支持FileReader
      if (!file || !window.FileReader) return;
      if (/^image/.test(file.type)) {
        //創(chuàng)建一個reader
        let reader = new FileReader();

        //將圖片轉(zhuǎn)成base64格式
        reader.readAsDataURL(file);
        //讀取成功后的回調(diào)
        reader.onloadend = function() {
          let result = this.result;
          let img = new Image();
          img.src = result;
          console.log("********未壓縮前的圖片大小********");
          console.log(result.length);
          img.onload = function() {
            let data = self.compress(img);
            self.imgUrl = result;

            let blob = self.dataURItoBlob(data);

            console.log("*******base64轉(zhuǎn)blob對象******");
            console.log(blob);

            var formData = new FormData();
            formData.append("file", blob);
            console.log("********將blob對象轉(zhuǎn)成formData對象********");
            console.log(formData.get("file"));
            let config = {
              headers: { "Content-Type": "multipart/form-data" }
            };
            // 發(fā)送請求;
            self.axios.post(self.uploadUrl.url, formData, config).then(res => {
              // console.log(res);
              // console.log(res.data.data.resultftphost)
              // console.log(res.data.data.resulturl)
              // this.$emit('')
              if (res.data.code == 200) {
                self.$emit(
                  "getImgsrc",
                  res.data.data.resultftphost,
                  res.data.data.resulturl
                );
              } else {
                self.$message({
                  message: "圖片上傳失敗,請重試",
                  type: "warning"
                });
              }
            });
          };
        };
      }
    },
    // 壓縮圖片
    compress(img) {
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext("2d");
      let initSize = img.src.length;
      let width = img.width;
      let height = img.height;
      canvas.width = width;
      canvas.height = height;
      // 鋪底色
      ctx.fillStyle = "#fff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, width, height);

      //進(jìn)行最小壓縮
      let ndata = canvas.toDataURL("image/jpeg", 0.1);
      // console.log("*******壓縮后的圖片大小*******");
      // console.log(ndata)
      // console.log(ndata.length);
      return ndata;
    },
    // base64轉(zhuǎn)成bolb對象
    dataURItoBlob(base64Data) {
      var byteString;
      if (base64Data.split(",")[0].indexOf("base64") >= 0)
        byteString = atob(base64Data.split(",")[1]);
      else byteString = unescape(base64Data.split(",")[1]);
      var mimeString = base64Data
        .split(",")[0]
        .split(":")[1]
        .split(";")[0];
      var ia = new Uint8Array(byteString.length);
      for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ia], { type: mimeString });
    },
    //刪除事件
    delImg() {
      this.imgUrl = null;
    }
  }
};

style 部分

.upload {
  position: relative;
  width: 200px;
  height: 220px;
  // 圖片展示
  .cha {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 6px;
    border: 1px dashed #cccccc;
    overflow: hidden;
    box-sizing: border-box;
    .layer {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 2;
      width: 100%;
      height: 200px;
      background-color: rgba(0, 0, 0, 0.3);
      text-align: center;
      line-height: 200px;
      opacity: 0;
      color: #ffffff;
      border: none;
    }
    .del {
      position: absolute;
      bottom: 0;
      right: 0;
      opacity: 0;
      z-index: 2;
      border: none;
    }
    img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 200px;
      border: none;
    }
  }
  //鼠標(biāo)放上時顯示刪除和放大
  .cha:hover .layer,
  .cha:hover .del {
    opacity: 1;
  }

  //點(diǎn)擊上傳
  .load {
    position: absolute;
    top: 0;
    left: 0;
    width: 200px;
    height: 200px;
    border: 1px dashed #cccccc;
    input {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      opacity: 0;
    }
  }
  .load::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 80%;
    border-right: 1px solid #cccccc;
  }
  .load:after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%);
    width: 80%;
    height: 1px;
    border-top: 1px solid #cccccc;
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垒玲,一起剝皮案震驚了整個濱河市陆馁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌合愈,老刑警劉巖叮贩,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異佛析,居然都是意外死亡妇汗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門说莫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杨箭,“玉大人,你說我怎么就攤上這事储狭』バ觯” “怎么了捣郊?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長慈参。 經(jīng)常有香客問我呛牲,道長,這世上最難降的妖魔是什么驮配? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任娘扩,我火速辦了婚禮,結(jié)果婚禮上壮锻,老公的妹妹穿的比我還像新娘琐旁。我一直安慰自己,他們只是感情好猜绣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布灰殴。 她就那樣靜靜地躺著,像睡著了一般掰邢。 火紅的嫁衣襯著肌膚如雪牺陶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天辣之,我揣著相機(jī)與錄音掰伸,去河邊找鬼。 笑死怀估,一個胖子當(dāng)著我的面吹牛碱工,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奏夫,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼怕篷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了酗昼?” 一聲冷哼從身側(cè)響起廊谓,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎麻削,沒想到半個月后蒸痹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呛哟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年叠荠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扫责。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡榛鼎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抡笼,我是刑警寧澤黄鳍,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布框沟,位于F島的核電站拧晕,受9級特大地震影響灾前,放射性物質(zhì)發(fā)生泄漏孟辑。R本人自食惡果不足惜饲嗽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一貌虾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衔憨,春花似錦袄膏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锌奴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間椭符,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工有咨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒸健,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像淳衙,于是被迫代替她去往敵國和親饺著。 傳聞我的和親對象是個殘疾皇子幼衰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容