-
Notifications
You must be signed in to change notification settings - Fork 10
/
composable.ts
72 lines (67 loc) · 1.59 KB
/
composable.ts
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
import type { ComputedRef, ComputedGetter, WatchSource } from 'vue';
import type { SetTitleFn } from './types';
import { inject, computed, ref, watch } from 'vue';
import { PAGE_TITLE, SET_PAGE_TITLE } from './injection-keys';
export type initialValue =
| string
| ComputedRef<string>
| ComputedGetter<string>
| WatchSource<string>;
/**
* Get current title or update it.
*
* ## Define initial title
*
* ```ts
* const { title } = useTitle('initial title`)
* ```
*
* ## React from ref state
*
* ```ts
* const name = ref('initial name')
* const { title } = useTitle(name)
* ```
*
* ## Use like a watch source argument
*
* ```ts
* const product = ref({ name: 'One Piece 1017' })
* const { title } = useTitle(() => product.name)
* ```
*
* ## Pass a computed as argument
*
* ```ts
* const product = ref({ name: 'One Piece 1017' })
* const name = computed(() => product.name)
* const { title } = useTitle(name)
* ```
*
* ## Use `setTitle` to dynamically change the title
*
* ```ts
* const product = ref({ name: 'One Piece 1017' })
* const { setTitle } = useTitle()
*
* watchEffect(() => {
* setTitle(product.name)
* })
* ```
*/
const useTitle = (
initial?: initialValue
): { title: ComputedRef<string>; setTitle: SetTitleFn } => {
const title = inject(PAGE_TITLE, ref<string>(''));
const setTitle = inject(SET_PAGE_TITLE, () => {});
if (typeof initial === 'string') {
setTitle(initial);
} else if (initial != null) {
watch(initial, setTitle, { immediate: true });
}
return {
title: computed(() => title?.value),
setTitle,
};
};
export { useTitle };