Vue + node.js(Express) 項目中實現換頭像與文件上傳

Vue + node.js(Express) 項目中實現換頭像與文件上傳

實現效果
在這裏插入圖片描述
上傳後
在這裏插入圖片描述

// html部分
<div class="head_img">
  <img :src="userInfo.avatar"/>
</div>
<div class="setting_right" @click.stop="uploadHeadImg">
  <div class="caption">更改頭像</div>
</div>
// display: none, 調用uploadHeadImg獲取到hiddenInput的dom執行點擊事件
<input type="file" accept="image/*" @change="handleFile" class="hiddenInput"/>

因爲input file的樣式不好改,所以直接display:none了,使用uploadHeaderImg操作DOM( 雖然Vue中不提倡 ), 但是香啊!!!

// Vue實例中
data () {
  return {
    userInfo: {
       avatar: ''
    }
  }
}
methods: {
    uploadHeadImg () {
      // 實現隱藏被點擊的效果, 這樣就可以不用修改input的樣式
      this.$el.querySelector('.hiddenInput').click()
    },
    handleFile (e) {
      let $target = e.target || e.srcElement
      // 獲取到上傳的file
      let file = $target.files[0]
	  // 創建FileReader的實例用於讀取文件
      let reader = new FileReader()

      // 生成表單格式
      let param = new FormData()
      // 加入參數字段
      param.append('file', file)
      param.append('userId', localStorage.getItem('userId'))

      // 無法直接查看param,可以用get的方法查看
      console.log(param.get('file'))
      console.log(param.get('userId'))
	
	  // axios請求
      axios.post('/api/user/addImg', param, {
        // application/x-www-form-urlencoded:默認編碼方式
        // multipart/form-data: 設置指定傳輸數據爲二進制數據,例如圖片、mp3、文件
        // text/plain:純文本的傳輸。空格轉換爲“+”,但不支持特殊字符編碼。
        headers: { 'Content-Type': 'multipart/form-data' }
      }).then(res => {
      	// 後端文件存儲完成後再進行圖片的讀取操作
        // 讀取file文件作爲base64格式
        reader.readAsDataURL(file)
      })
      
      // 讀取成功的操作  ( 更換頭像 )
      reader.onload = data => {
        let res = data.target || data.srcElement
        // res.result 爲圖片的base64格式, 直接放入img標籤的src中即可
        this.userInfo.avatar = res.result
      }
      // 讀取失敗的操作
      reader.onerror = (e) => {
        console.log('error' + e)
      }
    }
 }
// 安裝 multer 模塊
npm i multer -S

// 安裝 fs 模塊
npm i fs -S
// 引入模塊
const express = require("express");
router  = express.Router();
const multer = require('multer')
const upload = multer({dest: 'uploads/'})	// 配置圖片文件的路徑(沒有後綴名)
const fs = require('fs')

因爲multer模塊的上傳的圖片沒有後綴名,無法正常顯示
在這裏插入圖片描述
我們可以通過req.file獲取到文件的對象參數以及後綴名type,對文件進行拼接處理

// Express中 ( /api/user )
const express = require("express");
router  = express.Router();
const multer = require('multer')	// 引入 multer模塊
const upload = multer({dest: 'uploads/'})	// 配置圖片文件的路徑(沒有後綴名)

router.post('/addImg',upload.single('file'), (req, res, next) => {

  // 獲取到file的信息 ---> 只能通過req.file
  let fileObj = req.file
  
  // 獲取到body中userId信息
  let { userId } = req.body

  // 分割出type 
  let originalArr = fileObj.originalname.split('.')
  // 獲取到type ( jpg/png/gif )
  let type = originalArr[originalArr.length - 1]
  
  // 讀取文件 ( path, 'utf-8'(這裏不寫解碼類型,直接把回調函數中的data寫入新文件即可), callback)
  fs.readFile('uploads/' + fileObj.filename, (err, data) => {
    if (err) throw err

    // 創建複製圖片的路徑 以及 拼接type形成一個完整的圖片文件
    let newPath = '/img/headerImg/' + fileObj.filename + "." + type
    
    // 寫入複製的圖片 (path, data, callback)
    fs.writeFile('public' + newPath, data, (err) => { // 把讀取到的data寫入
      if (err) throw err

      // 刪除原uploads路徑下的圖片
      fs.unlink('uploads/' + fileObj.filename, () => {
      	res.send({
      	  code: '200',
      	  msg: '上傳成功'
      	})
      })
    })
  })
})

module.exports = router;

當然在配置multer的路徑的時候也可以直接配置需要存放的路徑
然後用fs模塊來修改文件的格式即可

const multer = require('multer')	// 引入multer模塊
const upload = multer({dest: 'public/img/headerImg'}) // 存放的路徑

router.post('/addImg',upload.single('file'), (req, res, next) => {

  // 獲取到file的信息 ---> 只能通過req.file
  let fileObj = req.file
  
  // 獲取到body中userId信息
  let { userId } = req.body

  // 分割出type ( jpg/png/gif )
  let originalArr = fileObj.originalname.split('.')
  let type = originalArr[originalArr.length - 1]
  
  // rename的參數1: 原文件的路徑和文件名(沒有後綴名無法顯示) 
  // 		 參數2: 修改後的文件路徑和文件名(有後綴名可以顯示)
  // 		 參數3: 回調函數
  fs.rename('public/img/headerImg' + fileObj.filename, 'public/img/headerImg' + '.' + type, err => {
  	if (err) throw err
  	res.send({
 	  code: '200',
 	  msg: '上傳成功'
  	})
  })
})

然後就可以顯示啦
在這裏插入圖片描述
當然在項目中後端還需要加入數據庫的操作,這裏沒有在接口中寫出來

把服務器中的路徑存入數據庫中,隨後每次讀取數據庫中的路徑放入src中就可以實現完整的效果了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章