vue-promisedとcomposition-apiがよさそう
vue-promisedとcomposition-apiを併用してみる
適当にコードだけ貼り付けていた記事がGoogleの検索上位にいたので,これでは情報が少なすぎる・・・・と思い書き直しました.
公式の次に出てくる記事がコード貼り付けて動かしてるだけじゃダメでしょ・・・・・・
vue-promisedとは
PromiseをUI側で処理してあげるのが旨味となります.
created, methodsでasync/awaitすれば解決じゃない?って思うかもしれませんが,Pendingの時はローディングを出して,resolveされたらコンテンツを表示,rejectされたらエラー表示するという時を考えてみます.
そうするとPromiseの状態をUIに伝えるためのFlag変数が必要となり意味の薄い変数がPromiseの数分だけ増えて行きますよね.そこでUI側でPromiseの状態を判別して適切なUIを返してくれるVue-Promiseが嬉しいというわけです.
Flagを持たせて書いてみる
<template> <div> <div v-if="isPending"> <p>loading</p> </div> <div v-else-if="isResolve"> <p>{{content}}</p> </div> <div v-else> <p>fetch error</p> </div> </div> </template> <script> import axios from "axios"; export default { data() { return { isPending: false, error: "", content: {}, } }, computed: { isResolve() { return !this.isPending && !error && !!content; } }, async created() { try { const res = await axios.get("http://example.com"); this.content = res.data; } catch (e) { this.error = "error"; console.error(e); } finally { this.isPending = false; } } } </script>
Vue-Promisedで書いてみる
template層で使うpromise変数にPromiseを渡せばいいです.他はtemplateそうがやってくれるのでロジック側ではPromiseの状態をハンドリングすることなく,resolveされた後のデータ,rejectされた後のデータをどう使うか,だけに絞って書くことができるので非常に簡潔に,そしてわかりやすくかけると思います.
PromiseはUIに任せる.Angulerだと普通みたいですが,僕はVue-Promisedに感激しました.
<template> <Promised id="app" :promise="promise"> <template v-slot:pending> <p>loading....</p> </template> <template v-slot="data"> <p>{{data}}</p> </template> <template v-slot:rejected="error"> {{error}} </template> </Promised> </template> <script> import { Promised } from "vue-promised"; import axios from "axios"; export default { components: { Promised }, data: { return { promise: axios.get("http://example.com") } } }; </script>
-----------------------------ここまで書き直した------------------------------------
vue-composition-api
vue-composition-api-rfc.netlify.com
<template> <Promised id="app" :promise="user"> <template v-slot:pending> <p>loading....</p> </template> <template v-slot="user"> <p>{{`${user.firstName}${user.lastName}`}}</p> </template> </Promised> </template> <script lang="ts"> import { createComponent, ref } from "@vue/composition-api"; import { Promised } from "vue-promised"; interface User { firstName: string; lastName: string; } export default createComponent({ components: { Promised }, setup() { const delayPromise = (time: number) => new Promise(resolve => { setTimeout(() => { resolve(); }, time); }); const fetchUser = async (): Promise<User> => { await delayPromise(1000); return { firstName: "naporitan", lastName: "napo" }; }; const user = ref(fetchUser()); return { user }; } }); </script>
promiseをそのまま変数に突っ込んでview側でpromiseを切り分けてくれるのでcreated, mountedで頑張らなくていいのとloadingフラグとか持たなくてよくなるので楽だなぁて感じです。
vue-promisedをjsxで書こうとしたら
JSX 要素型 'Promised' にはコンストラクトも呼び出しシグネチャも含まれていません。
って言われるんだけど、どうしたらいいんだろう。
vue-promised内部実装jsxじゃん
— 🍆naporitan🍆@うーねこ団 (@naporin24690) 2019年10月21日
だからできるはずなんだけどなぁ
Vueの情報収拾をほとんどここでやっています。ラジオ感覚で聞けて助かってる。 uit-inside.linecorp.com