Skip to content

Commit af1bd7f

Browse files
author
lmhcoding
committed
feat: add useHistory
1 parent 9ff92af commit af1bd7f

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ export * from './useStorage'
1313
export * from './useLifecycles'
1414
export * from './useInterval'
1515
export * from './useHash'
16+
export * from './useHistory'

src/useHistory.ts

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { reactive, toRefs, ToRefs, UnwrapRef } from 'vue'
2+
import { useEvent } from './useEvent'
3+
import { def } from './util'
4+
5+
type PathMethod = Extract<keyof History, 'replaceState' | 'pushState'>
6+
7+
function patchHistoryMethod(method: PathMethod): void {
8+
const history = window.history
9+
const origin = history[method]
10+
11+
def(
12+
history,
13+
method,
14+
function (this: History, state: any) {
15+
const result = origin.apply(this, (arguments as unknown) as Parameters<typeof origin>)
16+
const event: any = new Event(method.toLowerCase())
17+
event.state = state
18+
window.dispatchEvent(event)
19+
return result
20+
},
21+
true
22+
)
23+
}
24+
25+
patchHistoryMethod('pushState')
26+
patchHistoryMethod('replaceState')
27+
28+
export interface IHistoryState {
29+
state: any
30+
hash: string
31+
search: any
32+
host: string
33+
hostname: string
34+
href: string
35+
origin: string
36+
pathname: string
37+
port: string
38+
protocol: string
39+
}
40+
41+
function buildState(): IHistoryState {
42+
const { state } = window.history
43+
const { hash, search, host, hostname, href, origin, pathname, port, protocol } = window.location
44+
return {
45+
state,
46+
hash,
47+
search,
48+
host,
49+
hostname,
50+
href,
51+
origin,
52+
pathname,
53+
port,
54+
protocol
55+
}
56+
}
57+
58+
export function useHistory(): ToRefs<IHistoryState> {
59+
const state: UnwrapRef<IHistoryState> = reactive(buildState())
60+
useEvent('popstate', buildState)
61+
useEvent('pushstate' as any, buildState)
62+
useEvent('replacestate' as any, buildState)
63+
return toRefs(state)
64+
}

src/util.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export function def<T extends object>(obj: T, key: keyof T, val: any, enumerable?: boolean) {
2+
Object.defineProperty(obj, key, {
3+
value: val,
4+
enumerable: !!enumerable,
5+
writable: true,
6+
configurable: true
7+
})
8+
}

0 commit comments

Comments
 (0)