當我們在呼叫 API 後,通常會有很多後續的功能接續運作,例如:更換狀態、顯示錯誤訊息、使用 try catch blocks 等等。來看看這個搜尋範例是怎麼把程式碼抽取出來。
搜尋範例
我們先來看這段程式碼。
/src/App.js
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <template> <div> Search for <input v-model="searchInput" /> <div> <p>Loading: {{ loading }}</p> <p>Error: {{ error }}</p> <p>Number of events: {{ results }}</p> </div> </div> </template> <script> import { ref, watch } from "@vue/composition-api"; import eventApi from "@/api/event.js";
export default { setup() { const searchInput = ref(""); const results = ref(null); const loading = ref(false); const error = ref(null); async function loadData(search) { loading.value = true; error.value = null; results.value = null; try { results.value = await eventApi.getEventCount(search.value); } catch (err) { error.value = err; } finally { loading.value = false; } } watch(searchInput, () => { if(searchInput.value !== "") { loadData(searchInput); } else { results.value = null; } }); return { searchInput, results, loading, error }; } }; </script>
|
如果在瀏覽器看起來會是這樣。
程式碼抽取
接下來我們試著把 api 這段抽取出來。
composables/use-promise.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { ref } from "@vue/composition-api";
export default function usePromise(fn) { const results = ref(null); const loading = ref(false); const error = ref(null); const createPromise = async (...args) => { loading.value = true; error.value = null; results.value = null; try { results.value = await fn(...args); } catch (err) { error.value = err; } finally { loading.value = false; } } return { results, loading, error, createPromise }; }
|
然後我們把抽取出來的程式碼,替代回原本的 App.js。
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 26 27 28 29 30 31 32
| <template> <div> Search for <input v-model="searchInput" /> <div> <p>Loading: {{ getEvents.loading }}</p> <p>Error: {{ getEvents.error }}</p> <p>Number of events: {{ getEvents.results }}</p> </div> </div> </template> <script> import { ref, watch } from "@vue/composition-api"; import eventApi from "@/api/event.js"; import usePromise from "@/composables/use-promise";
export default { setup() { const searchInput = ref(""); const getEvents = usePromise(search => eventApi.getEventCount(search.value) ); watch(searchInput, () => { if(searchInput.value !== "") { getEvents.createPromise(searchInput); } else { getEvents.results.value = null; } }); return { searchInput, getEvents }; } }; </script>
|
這樣就完成程式碼的抽取替換囉~另外要注意的事,如果用 Vue 2 的話,html 的部分都要再多加 .value 才會抓到值,但如果是直接用 Vue 3 的話,上面程式碼就能直接正常運行。
參考資料