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
