用兩支 API 實作新增資料與上傳檔案
實作新增資料與上傳檔案有兩種做法
- 開一支 API 處理新增使用者,設定成 multipart/form-data 就可以同時上傳檔案和使用者資料。
- 開一支上傳檔案的 API,處理檔案,另一支就處理要儲存到資料庫的使用者資料。上傳之後的 path 放在資料庫的任務就交給了前端。
在講的是第二種方法,想要在 POST User 時,先上傳大頭照,再把 path 放到使用者資料。
之後會專門寫一篇文章,講「多個動作的同步資料整理」。
¶API 文件
遇到這種 API,怎麼做呢?
¶POST /user/:id
request body
{
name: 'chris',
avatar: 'http://127.0.0.1/img/user_1.jpg'
}
**response 200 **
(略)
¶POST /file
request header
{
'Content-Type': 'multipart/form-data'
}
request body
form-data
{
file: (binary)
}
**response 200 **
{
data: '/file/:file_path'
}
¶依照 API 文件寫 vuex
依前幾天建立的默契,可以知道
- state 要建立 file
state: {
file: null
},
- mutations 要建立 file
mutations: {
file(state, payload) {
state.file = payload
}
},
- getters 要建立 file
getters: {
file: state => state.file
},
這些一定要做。
- 避免直接存取資料
- 需要時可以擋住格式不符
- 可以使用 devtool 的 hook
- 增加資料的抽象化
另外特別的地方
- 資料直送的情況,mutation 和 getters 的命名要相同。
- 資料有特別處理,會增加不同名字的 getters。
所以
要 file 可以用 $store.getters.file 就取得
@/store/actions.js
import backendAPI from '@/utility/backendAPI.js'
export default {
async uploadFile({ commit, getters }) {
const file = getters.file;
const res = await backendAPI.formDataPOST(`/file`, { file })
return res.data
}
// ...
}
src/store/user/actions.js
在 createUser 上面加上 uploadFile
import backendAPI from '@/utility/backendAPI.js'
export default {
async createUser({ dispatch, getters }, { name }) {
if (getters.file != null) {
const res = await dispatch('uploadFile');
await backendAPI.POST(`/user`, {
name,
avatar: res.data,
});
} else {
await backendAPI.POST(`/user`, {
name,
});
}
},
// ...
}
在新增時就可以直接
onSubmit() {
this.$store.dispatch('createUser', this.$store.getters.user);
}
¶另一種不推薦的做法
直接在選取完檔案之後,就將檔案先上傳。而不是等到要新增人員時才上傳。
缺點: 在一次修改的過程中,不斷的換掉檔案,就會不斷的上傳,導致伺服器上的垃圾檔案會更新變多。
發表於