Appearance
asyncData 方法
midway-vue3-ssr
扩展了 Vue.js,增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能获取或处理数据。
说明
asyncData
方法会在组件每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为 store 、 route、router 和 ctx(服务端存在)的集合IAsyncDataContext
类型,你可以利用 asyncData方法来获取数据。
类型
import { Context } from '@midwayjs/koa';
import { RouteLocationNormalizedLoaded, Router } from 'vue-router';
import { Pinia } from 'pinia';
export interface IAsyncDataContext {
route: RouteLocationNormalizedLoaded;
store: Pinia;
router: Router;
ctx?: Context; // 在服务端运行时存在
}
declare module 'vue' {
interface ComponentCustomOptions {
asyncData?(context: IAsyncDataContext): Promise<any>;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
使用
async
<script lang="ts">
import { defineComponent} from 'vue'
import { useAboutStore, IAboutState } from "./store";
export default defineComponent({
async asyncData({store, route}) {
const aboutStore = useAboutStore(store);
await aboutStore.getList({current: Number(route.query.page || 1)});
}
})
</script>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
数据展示
<script lang="ts" setup>
import { useAboutStore, IAboutState } from "./store";
// 读取数据
const aboutStore = useAboutStore();
const tableData = computed<IAboutState>(()=>aboutStore.$state);
</script>
<template>
<div class="about">
<h1>This is an about page</h1>
<div class="box">
<ul v-loading="tableData.loading">
<li v-for="item in tableData.list">
<div>
<router-link :to="{ path: '/detail', query: { id: item.id }}">
{{item.title}}
</router-link>
<span>{{item.addtime}}</span>
</div>
</li>
</ul>
</div>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
监听 query 参数改变
默认情况下,query 的改变不会调用 asyncData
方法。如果需要,可以监听这个行为。例如,在构建分页组件时,您可以设置 watch
监听参数。如下样列:
<script lang="ts">
import { defineComponent, computed, watch } from 'vue'
import { useRoute } from "vue-router"
import Pagination from "@/components/Pagination/base.vue";
import { useAboutStore, IAboutState } from "./store";
export default defineComponent({
async asyncData({store, route}) {
const aboutStore = useAboutStore(store);
await aboutStore.getList({current: Number(route.query.page || 1)});
}
})
</script>
<script lang="ts" setup>
// 读取数据
const aboutStore = useAboutStore();
const tableData = computed<IAboutState>(()=>aboutStore.$state);
const route = useRoute();
const page = computed(()=>route.query.page);
watch(page,()=> {
if(route.path !== '/about') {
return;
}
aboutStore.getList({current: Number(page.value || 1)});
})
</script>
<template>
<div class="about">
<h1>This is an about page</h1>
<div class="box">
<ul v-loading="tableData.loading">
<li v-for="item in tableData.list">
<div>
<router-link :to="{ path: '/detail', query: { id: item.id }}">
{{item.title}}
</router-link>
<span>{{item.addtime}}</span>
</div>
</li>
</ul>
<div>
<pagination :total="tableData.pagination.total" :current-page="tableData.pagination.current" page-url="/about?page={page}"></pagination>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.box {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
text-align: left;
ul {
li {
padding: 5px 0;
div {
display: flex;
justify-content: space-between;
}
}
}
}
@media (max-width: 767px) {
.box {
padding: 15px;
}
}
</style>
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74