Vue 版的 Custom Hook-Composables

跟 React 一樣棒的功能。

簡述

這個功能我覺得就跟 React 的 Custom Hook 幾乎一樣,所以我就不解釋太深了,簡單來說就是把原本在 setup 中的邏輯抽出去寫成「一個 module」,接著再到元件中拿進來用就好。

這種作法被稱為「Composables」或「Composition Function」,不過這只是一種俗稱而已,並不是官方定義的名稱。

總之先來一段常見的 fetch 範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
import { ref } from '@vue/reactivity'

export default {
setup() {
const posts = ref([])
const error = ref(null)

const getPosts = async () => {
try {
const response = await fetch('http://localhost:3000/posts')
if (!response.ok) throw new Error('No data available')
const data = await response.json()
posts.value = data
} catch (exception) {
error.value = exception.message
}
}

getPosts()

return { posts, error }
}
}
</script>

寫過 React 的 custom hook 的話就會知道,我們這一段其實可以抽出去寫成一個 hook,只要記得在最後把 postserror 這兩個「state」給 return 出來就行了。

Vue 也是在做差不多的事情,我們可以建立一支 src/composables/useFetch,然後寫入這樣的內容:

附註:這邊的名稱只是因為想不到更好的命名而參考 React hook 的風格,Vue 裡面並沒有要求要 use- 來當前綴哦,你想取啥都能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { ref } from 'vue'

export const useFetch = (url) => {
const data = ref([])
const error = ref(null)

const getPosts = async () => {
try {
const response = await fetch(url)
if (!response.ok) throw new Error('No data available')
const json = await response.json()
data.value = json
} catch (exception) {
error.value = exception.message
}
}

// trigger when call this hook
getPosts()

// expose states
return { data, error }
}

接著原本的檔案就可以簡化為這樣:

1
2
3
4
5
6
7
8
9
10
11
12
<script>
import { useFetch } from '@/composables/useFetch'

export default {
setup() {
const url = 'http://localhost:3000/posts'
const { data, error } = useFetch(url)
// 如果想重新命名的話得在這邊「輸出」的時候改才行
return { posts: data, error: error }
}
}
</script>
Vue-Composition API(useRouter & useRoute) Vue-Composition API(Life Cycle Hooks)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×