defineColadaLoader
This commit is contained in:
141
src/pages/data-loaders.[id]/sub-1.[userId].page.vue
Normal file
141
src/pages/data-loaders.[id]/sub-1.[userId].page.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<script lang="ts">
|
||||
import { defineColadaLoader } from 'unplugin-vue-router/data-loaders/pinia-colada';
|
||||
|
||||
async function getUserById(id: string, { signal }: { signal?: AbortSignal }) {
|
||||
console.warn('[getUserById] 被调用, id :>> ', id);
|
||||
setTimeout(() => {
|
||||
console.log('5s 已过', 'id :>> ', id);
|
||||
}, 5000);
|
||||
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`, { signal });
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
export const useUserData = defineColadaLoader('DataLoadersIdSub1UserId', {
|
||||
async query(to, { signal }) {
|
||||
console.debug('[defineColadaLoader] query');
|
||||
return getUserById(to.params.userId, { signal });
|
||||
},
|
||||
key: (to) => ['users', to.params.userId],
|
||||
// Keep the data "fresh" 10 seconds to avoid fetching the same data too often
|
||||
// 保持数据“新鲜”10秒,以避免过于频繁地获取相同的数据
|
||||
staleTime: 5000,
|
||||
});
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { data: user, status, error, isLoading, reload, refresh } = useUserData();
|
||||
|
||||
const route = useRoute('DataLoadersIdSub1UserId');
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div flex="~ row">
|
||||
<button class="green" @click="$router.back()">Back</button>
|
||||
</div>
|
||||
<h1>Pinia Colada Loader Example</h1>
|
||||
<pre>route.params: {{ route.params }}</pre>
|
||||
|
||||
<fieldset>
|
||||
<legend>Controls</legend>
|
||||
|
||||
<button @click="refresh()">Refresh</button>
|
||||
<button @click="reload()">Refetch</button>
|
||||
</fieldset>
|
||||
|
||||
<div class="flex items-center">
|
||||
<RouterLink :to="{ params: { userId: (Number(route.params.userId) || 0) - 1 } }">
|
||||
Previous
|
||||
{{ (Number(route.params.userId) || 0) - 1 }}
|
||||
</RouterLink>
|
||||
|
|
||||
<RouterLink :to="{ params: { userId: (Number(route.params.userId) || 0) + 1 } }">
|
||||
Next {{ (Number(route.params.userId) || 0) + 1 }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<h2>State</h2>
|
||||
|
||||
<p>
|
||||
<code>status: {{ status }}</code>
|
||||
<br />
|
||||
<code>isLoading: {{ isLoading }}</code>
|
||||
</p>
|
||||
<pre v-if="error">Error: {{ error }}</pre>
|
||||
<pre v-else>{{ user == null ? String(user) : user }}</pre>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.green {
|
||||
background-color: #42b883;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #4a4a4a;
|
||||
padding: 16px;
|
||||
margin: 16px 0;
|
||||
border-radius: 8px;
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
|
||||
legend {
|
||||
padding: 0 8px;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 8px;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #4a4a4a;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
background-color: #333333;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #1e1e1e;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #2a2a2a;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #42b883;
|
||||
text-decoration: none;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
color: #5ccfaa;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #e0e0e0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #42b883;
|
||||
margin-top: 24px;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user