一、前言
項目演示:每個新用戶登錄之后會有個默認的頭像,用戶可以根據自己選擇自己的頭像圖片進行更改。

二、主要內容
1、需求實現的思路分析。
第一步:用戶點擊按鈕選擇圖片其實是間接觸發input圖片選擇
第二步:input表單被監聽change事件
第三步:選擇圖片,然后將圖片用canvas畫在預覽框處
第四步:點擊“確定按鈕”,請求后端接口配合雲存儲,將圖片上傳到雲存儲上
第五步:利用雲存儲器中生成的圖片url地址替換掉原來的地址
2、具體實現
2.1總體思路

2.2前台實現部分
(2)chooseImg(): 如上面所示這里用了一個小技巧點擊下面的“選擇圖片”按鈕,間接點擊input輸入框
//間接點擊input框 chooseImg(){ var avater = this.$refs.avater //input框 avater.click() //input框點擊 avater.click() //這里要設置兩次才有用 },
(3)changeImg($event)這個函數監聽到了input的圖片發生了改變 , 注意:如果changeImg(e) 這樣寫獲取不到事件e對象,改為changeImg($event)這樣獲取試試
//changeImg()函數將選中的圖片繪制到頁面中 changeImg(event){ console.log(111) var files = event.target.files if(files.length===0){//沒有選中 return; } var imgPreview//新建一個緩沖區象允許Web應用程序異步讀取存儲在用戶計算機上的文件。 var length = files.length for(let i=0; i<length; i++){ this.file = files[i] imgPreview = new FileReader() if(this.file.size > this.maxSize){//規定了一個圖片大小的最大上限 Toast('圖片太大,不允許上傳') return; } } //加載選中的圖片 imgPreview.onload=(event)=>{ let newimg = new Image() newimg.onload = ()=>{//圖片預覽 //創建畫布 let canvas = document.createElement('canvas') let ctx = canvas.getContext('2d') let width = newimg.width let height = newimg.height //設置畫布的大小 canvas.width = width; canvas.height = height ctx.drawImage(newimg, 0, 0, width, height) let newimgUrl = canvas.toDataURL('image/png')//方法返回一個包含圖片展示的 data URI 。可以使用 type 參數其類型,默認為 PNG 格式。圖片的分辨率為96dpi。 this.avater = newimgUrl console.log(this.avater) } newimg.src = event.target.result; } imgPreview.readAsDataURL(this.file)//readAsDataURL 方法會讀取指定的 Blob 或 File 對象。讀取操作完成的時候,readyState 會變成已完成DONE },
(4)點擊“確定”上傳圖片
//確定更新 upDateOk(){ if(!this.file){ Toast('請選擇新的頭像') return } // Indicator.open('頭像更新中...') let self = this let param = new FormData()//FormData對象用以將數據編譯成鍵值對 param.append('username',this.userInfo._id) param.append('avater',this.file) console.log(param) if(this.userInfo.avater!== 'http://localhost:4000/public/images/ava.jpg'){//如果用戶的頭像不是默認的那一張頭像也需要將當前的這一張頭像的地址傳過去 param.append('oldVal', this.userInfo.avater) } let headers = { headers:{ "Content-Type": "application/x-www-form-urlencoded" } } //請求更新頭像的方法 self.$axios.post('/api/upload/uploadAvater',param, headers).then(function(result){ self.$router.push({path: '/home'}); Indicator.close(); Toast(result.data.msg) }) } }
2.3后端node.js實現部分
(1)第一步:需要去雲存儲器上去申請賬號和密碼,創建存儲桶,會生成需要用到的密匙(百度步驟很多)
(2)參考阿里雲輔助文檔:https://help.aliyun.com/document_detail/111265.html?spm=a2c4g.11186623.6.1239.45af2778FtkZdG

阿里雲上借助的put方法實現上傳功能,方法如下:

(3)multer標簽實現的圖片上傳,所以需要安裝multer
var fileName var filePath let Storage = multer.diskStorage({//diskStorage()方法指定文件存儲的文件路徑或者文件名 destination: function (req, file, callback) {//計算圖片存放地址 callback(null, './public/images'); }, filename: function (req, file, callback) {//圖片文件名 fileName = Date.now() + '_' + parseInt(Math.random() * 1000000) + '.png'; filePath = './public/images/' + fileName; callback(null, fileName) } }); let upload = multer({storage: Storage}).any()//接受一切上傳的文件。文件數組將保存在 req.files。 let avater = multer({storage: Storage}).single('avater')//接受一個以 fieldname 命名的文件。這個文件的信息保存在 req.file。
(4)前端請求對應的后端接口,實現圖片上傳
router.post('/uploadAvater', function (req, res, next) {
avater(req, res, function (err) {
let username = req.body.username;//獲取到當前用戶的id
console.log(username)
let imgs;
let oldVal = req.body.oldVal || '';
if (oldVal) {
oldVal = oldVal.replace('http://pfr020xzs.bkt.clouddn.com/', '');
client.delete(oldVal, function (err) {
if (err) {
console.log(err)
}
})
}
if (err) {
return res.end(err);
}
let i = 0;
let imgItem = req.file;
let filePath = `./public/images/${imgItem.filename}`;
//調用上面的put方法實現圖片上傳
put(fileName,filePath,(result)=>{
imgs = result.url;
console.log(imgs)
User.update({
_id: username
}, {
avater: imgs
}).then(() => {
res.json({
code: '0',
msg: '上傳成功'
});
})
});
});
});
