talk is cheap show me the codejavascript
具體的樣式配置能夠見element-ui的官網前端
第一種配置:選擇圖片後直接上傳(action是服務器地址,http-request是上傳到服務器前攔截request進行處理的操做):vue
<el-upload
class="upload-demo"
ref="upload"
:action=domain
:http-request=uploadImage
:file-list="fileList"
list-type="picture-card"
:before-upload="beforeUpload"
multiple>
<i class="el-icon-plus"></i>
<div class="el-upload__tip" slot="tip">只能上傳jpg/png文件,且不超過500kb</div>
</el-upload>
複製代碼
一個參考的uploadImage()函數配置(這裏主要須要重命名圖片名,我使用mongoose的Types生成一個惟一的ObjectId來進行重命名,也能夠使用時間戳等方式):java
async uploadImage(req) {
const config = {
headers: {'Content-Type': 'multipart/form-data'}
};
let filetype = ''
if (req.file.type === 'image/png') {
filetype = 'png'
} else {
filetype = 'jpg'
}
const keyName = this.bucket + "-" + Types.ObjectId().toString() + '.' + fileType;
const formdata = new FormData();
formdata.append('file', req.file);
formdata.append('key', keyName);
axios.post('/api/uploadImage', formdata, config)
.then(res => {
this.fileList.push({
name: res.data.name,
url: res.data.url,
});
console.log('image upload succeed.');
})
.catch(err => {
console.log(err.message)
})
},
複製代碼
注意到:咱們若是將圖片上傳到一個跨域服務器是須要進行跨域處理的,後面咱們就能夠使用'/api'代替服務器地址。
① 在Vue中咱們能夠修改config/index.js:ios
proxyTable: {
'/api': {
target: 'https://example.com', // 接口的域名
secure: false, // 若是是https接口,須要配置這個參數
changeOrigin: true, // 若是接口跨域,須要進行這個參數配置
pathRewrite: {'^/api': ''}
}
},
複製代碼
② 在Nuxt中咱們能夠配置nuxt.config.js:express
modules: ['@nuxtjs/axios','@nuxtjs/proxy'],
proxy: [
'/api',
{
target: 'https://example.com',
pathRewrite: {'^/api': '/'}
}
],
複製代碼
另外一種配置:點擊上傳按鈕後才上傳到服務器(主要將上傳組件的:auto-upload
設置爲false
)。若是要實現圖片預覽能夠添加一個處理函數:on-change="handleSuccess"
:element-ui
handleSuccess(res, files) {
this.fileList = [];//由於我這裏每次上傳只選擇一張圖片,因此清空
let file = files[files.length - 1];
let name = file.name;
if(this.beforeUpload(file.raw)) {
let imageUrl = window.URL.createObjectURL(file.raw);
this.imageFile = file;//保存imageFile
this.fileList.push({name: name, url: imageUrl});
}
},
複製代碼
上傳到七牛雲能夠對uploadImage()函數進行修改:json
try {
//獲取上傳憑證token
let uptoken = await this.$store.dispatch('getUploadToken');
const formdata = new FormData();
formdata.append('file', this.imageFile.raw);
formdata.append('token', uptoken);//添加憑證
formdata.append('key', keyName);
return new Promise((resolve, reject) => {
axios.post('/upQiniu', formdata, config).then(res => {
this.imageUrl = 'http://' + this.qiniuaddr + '/' + res.data.key;
this.fileList = [];
this.imageFile = null;
resolve(this.imageUrl);
});
});
} catch (e) {
console.log('post failed!' + e.message);
}
複製代碼
後面咱們要上傳能夠直接調用uploadImage函數異步返回圖片上傳後的路徑axios
const qiniu = require('qiniu')
//util/onfig/qiniu.js中放置七牛雲的訪問key和密鑰
import {accessKey, secretKey} from '../util/config/qiniu'
//例如我在Vuex Store的action中添加了如下函數
getUploadToken() {
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const options = {
scope: 'xxxxx',//你在七牛雲的空間名字
};
const putPolicy = new qiniu.rs.PutPolicy(options);
return putPolicy.uploadToken(mac);
},
複製代碼
router.post('/uploadImage', async(req, res, next) => {
var form = new multiparty.Form();
form.uploadDir = config.imagePath;
form.maxFieldsSize = 2 * 1024 * 1024;
var newName;
await form.parse(req, (err, fields, files) => {
if(err) {
return res.status(500).json({message: "upload image failed: " + err});
}
newName = fields.key[0];//由於element-ui每次上傳一張圖片,因此這裏考慮取出第一個便可
let newPath = config.imagePath + newName;
let originalPath = files.file[0].path;
try {
fs.existsSync(originalPath);//本地圖片路徑是否存在
fs.renameSync(originalPath,newPath);//重命名,這裏最好使用renameSync強制命名
return res.status(200).json({name: newName, url: config.imageURL + newName});
} catch (error) {
return res.status(500).json({message: "upload image failed: " + error});
}
});
});
複製代碼
一個是上傳的formdata配置,注意配置config,若是上傳失敗檢查request中的formdata是否爲空;另外一個是跨域配置。segmentfault
一個小記錄,歡迎指教