|
30 | 30 | type FunctionalComponent,
|
31 | 31 | type DefineComponent,
|
32 | 32 | computed,
|
| 33 | + onActivated, |
| 34 | + onDeactivated, |
33 | 35 | } from "vue";
|
34 | 36 | import _ from "lodash";
|
35 | 37 |
|
|
87 | 89 | const fetchedContent = ref<T>();
|
88 | 90 | const firstLoad = ref(false);
|
89 | 91 | const hydrated = ref(false);
|
| 92 | + /** |
| 93 | + * Whether component was deactivated by keep-alive |
| 94 | + */ |
| 95 | + const deactivated = ref(false); |
90 | 96 | /**
|
91 | 97 | * Hydrate content
|
92 | 98 | *
|
93 | 99 | * Useful with firebase client approach
|
94 | 100 | */
|
95 | 101 | const hydrate: tHydrate<T> = (newContent, newErrors) => {
|
96 | 102 | // prevent hydration
|
| 103 | + if (deactivated.value) return; |
97 | 104 | if (fetchedContent.value && !hydrated.value) return (hydrated.value = true);
|
98 | 105 | if (!props.preventAutoload && !firstLoad.value) return;
|
99 | 106 |
|
|
107 | 114 | }
|
108 | 115 |
|
109 | 116 | async function refresh() {
|
| 117 | + // prevent refresh |
| 118 | + if (deactivated.value) return; |
| 119 | +
|
110 | 120 | try {
|
111 | 121 | if (props.promise || props.hydratablePromise || props.url) {
|
112 | 122 | loading.value = true;
|
|
150 | 160 | // Allow the parent to manually force an update
|
151 | 161 | emit("refresh", refresh);
|
152 | 162 |
|
153 |
| - // refetch on url or promise change |
| 163 | + function validatePromiseLike(newPromise: any, oldPromise: any) { |
| 164 | + /** |
| 165 | + * The same promise would trigger the watcher |
| 166 | + * We assume here that the same promise is provided |
| 167 | + */ |
| 168 | + const possibleSamePromise = !!newPromise && !!oldPromise; |
| 169 | +
|
| 170 | + // prevent muntiple requests |
| 171 | + if (newPromise === oldPromise || !!possibleSamePromise) return; |
| 172 | +
|
| 173 | + // refresh |
| 174 | + if (!loading.value && !!newPromise) refresh(); |
| 175 | + } |
| 176 | +
|
| 177 | + // lifecycle, refetch on url or promise change |
154 | 178 | watch(
|
155 | 179 | () => props.url,
|
156 | 180 | (newUrl, oldUrl) => {
|
|
162 | 186 | },
|
163 | 187 | { immediate: false }
|
164 | 188 | );
|
165 |
| - watch( |
166 |
| - () => props.promise, |
167 |
| - (newPromise, oldPromise) => { |
168 |
| - /** |
169 |
| - * The same promise would trigger the watcher |
170 |
| - * We assume here that the same promise is provided |
171 |
| - */ |
172 |
| - const possibleSamePromise = !!newPromise && !!oldPromise; |
173 |
| -
|
174 |
| - // prevent muntiple requests |
175 |
| - if (newPromise === oldPromise || !!possibleSamePromise) return; |
176 |
| -
|
177 |
| - // refresh |
178 |
| - if (!loading.value && !!newPromise) refresh(); |
179 |
| - }, |
180 |
| - { immediate: false } |
181 |
| - ); |
182 |
| - // load if the firstLoad was prevented |
| 189 | + watch(() => props.promise, validatePromiseLike, { immediate: false }); |
| 190 | + watch(() => props.hydratablePromise, validatePromiseLike, { immediate: false }); |
183 | 191 | watch(
|
184 | 192 | () => props.preventAutoload,
|
185 | 193 | (prevent) => {
|
| 194 | + // load if the firstLoad was prevented |
186 | 195 | if (!prevent && !firstLoad.value) refresh();
|
187 | 196 | },
|
188 | 197 | { immediate: false }
|
189 | 198 | );
|
190 |
| - // Refresh if payload changes |
191 | 199 | watch(
|
192 | 200 | () => props.payload,
|
193 | 201 | (newPayload, oldPayload) => {
|
| 202 | + // Refresh if payload changes |
194 | 203 | if (firstLoad.value && !_.isEqual(newPayload, oldPayload)) refresh();
|
195 | 204 | },
|
196 | 205 | { immediate: false }
|
197 | 206 | );
|
| 207 | +
|
| 208 | + onActivated(() => { |
| 209 | + deactivated.value = false; |
| 210 | + }); |
| 211 | + onDeactivated(() => { |
| 212 | + deactivated.value = true; |
| 213 | + }); |
198 | 214 | </script>
|
0 commit comments