1+ import { defineComponent , PropType , computed , SlotsType , unref , watch } from "vue" ;
2+ import useRequest from "../useRequest" ;
3+ import type {
4+ UseRequestService ,
5+ UseRequestOptions ,
6+ UseRequestPlugin ,
7+ } from "../types" ;
8+
9+ // 泛型工厂
10+ function createUseRequestQueryComponent < TData = any , TParams extends unknown [ ] = any [ ] > ( ) {
11+ // 先定义组件
12+ const Comp = defineComponent ( {
13+ name : "UseRequest" ,
14+ props : {
15+ service : {
16+ type : Function as PropType < UseRequestService < TData , TParams > > ,
17+ required : true ,
18+ } ,
19+
20+ initialData : {
21+ type : String ,
22+ default : ( ) => undefined ,
23+ } ,
24+ ready : {
25+ // 支持 initialData
26+ type : Object as PropType <
27+ UseRequestOptions < TData , TParams > [ 'ready' ]
28+ > ,
29+ default : ( ) => ( {
30+ ready : false ,
31+ } ) ,
32+ } ,
33+ refreshDeps : {
34+ type : Array as PropType < any [ ] > ,
35+ default : ( ) => [ ] ,
36+ } ,
37+ plugins : {
38+ type : Array as PropType < UseRequestPlugin < TData , TParams > [ ] > ,
39+ default : ( ) => [ ] ,
40+ } ,
41+ } ,
42+ slots : Object as SlotsType < {
43+ default : ( props : Pick < ReturnType < typeof useRequest < TData , TParams > > , "data" > ) => any ,
44+ loading : ( ) => any ,
45+ error : ( props : { error : ReturnType < typeof useRequest < TData , TParams > > [ "error" ] [ 'value' ] } ) => any ,
46+ target ?: ( ) => any
47+ } > ,
48+ setup ( props , { slots } ) {
49+
50+ // 支持响应式 props
51+ const service = computed ( ( ) => unref ( props . service ) ) ;
52+ const plugins = computed ( ( ) => unref ( props . plugins ) ) ;
53+
54+
55+ // 让 props 转为响应式
56+ const ready = computed ( ( ) => props . ready ) ;
57+ const refreshDeps = computed ( ( ) => props . refreshDeps ) ;
58+
59+
60+ // useRequest 的返回类型会自动推断
61+ const result = useRequest ( service . value , {
62+ // @ts -ignore
63+ initialData : props . initialData ,
64+ // @ts -ignore
65+ ready,
66+ // @ts -ignore
67+ refreshDeps,
68+ } , plugins . value ) ;
69+
70+ watch (
71+ refreshDeps ,
72+ ( ) => {
73+ result . refresh ( ) ;
74+ } ,
75+ { immediate : true , deep : true }
76+ ) ;
77+
78+ return ( ) => {
79+ if ( result . loading . value && slots . loading ) {
80+ return slots . loading ( ) ;
81+ }
82+ if ( result . error . value && slots . error ) {
83+ return slots . error ( { error : result . error . value } ) ;
84+ }
85+ if ( ! result . loading . value && ! result . error . value && slots . default ) {
86+
87+ return slots . default ( {
88+ // @ts -ignore
89+ data : result . data . value
90+ } ) ;
91+ }
92+ return null ;
93+ } ;
94+ } ,
95+ } ) ;
96+
97+ // 用类型断言给组件加上 slots 类型声明
98+ return Comp
99+ }
100+
101+ // 导出泛型组件工厂
102+ export default createUseRequestQueryComponent ;
0 commit comments