處理 RESTful API 的 GET 回傳 Primitive 在實務上一定會碰到,由於 Composition API 沒有使用 this
,在 Vue 3 將有不同處理方式。
Version
Vue 3.0.11
Composition API
按下 Get Book
會從 API 獲得 title
。
api/getBook.js
import axios from 'axios'
export default id => axios.get(`/book/${id}`)
使用 axios.get
回傳 Promise。
App.vue
<template lang='pug'>
div
button(@click='onClick') Get Book
div {{ title }}
</template>
<script setup>
import getBook from '/src/api/getBook'
ref: title = ''
let onClick = () => {
getBook(1)
.then(x => x.data)
.then(x => title = x.title)
.catch(e => console.error (e.response.data.error))
}
</script>
第 8 行
import getBook from '/src/api/getBook'
引用 API function 從 API 取得 data。
10 行
ref: title = ''
使用 ref sugar 定義 title
state 較適合 Composition API。
12 行
let onClick = () => {
getBook(1)
.then(x => x.data)
.then(x => title = x.title)
.catch(e => console.error (e.response.data.error))
}
由於 getBook
回傳 Promise,因此使用 then()
寫入 side effect。
由於不必透過 this
讀取 title
state,因此 onClick()
可安心使用 arrow function,不必再使用 function expression。
Point-free
結果不變,但使用 Point-free 改寫。
api/getBook.js
import axios from 'axios'
export default id => _ => axios.get(`/book/${id}`)
使用 axios.get
回傳 Promise。
App.vue
<template lang='pug'>
div
button(@click='onClick') Get Book
div {{ title }}
</template>
<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, andThen as then, path, otherwise } from 'ramda'
import { error } from 'wink-fp'
import getBook from '/src/api/getBook'
let title = ref ('')
let errorHandling = pipe (
path (['response', 'data', 'error']),
error
)
let onClick = pipe (
getBook (1),
then (path (['data', 'title'])),
then (write (title)),
otherwise (errorHandling)
)
</script>
14 行
let title = ref ('')
使用 ref
定義 title
state 較適合 Point-free。
21 行
let onClick = pipe (
getBook (1),
then (path (['data', 'title'])),
then (write (title)),
otherwise (errorHandling)
)
使用 pipe
組合 onClick
:
getBook (1)
:將id
傳入getBook
回傳 Promisethen (path (['data', 'title']))
:在 Resolved Promise 內取出data.title
then (write (title))
:在 Resolved Promise 內寫入title
stateotherwise (errorHandling)
:傳入errorHandling
處理 Rejected Promise
16 行
let errorHandling = pipe (
path (['response', 'data', 'error']),
error
)
使用 pipe
組合 errorHandling
:
path (['response', 'data', 'error'])
:在 Rejected Promise 內取出response.data.error
error
:印出錯誤訊息
Conclusion
- Vue 3 Composition API 由於沒有使用
this
,使得 Point-free 成為可能,event handler 都可以直接以 pure function 組合出來