Skip to content

Commit

Permalink
feat: add useHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
lmhcoding committed Sep 20, 2020
1 parent 9ff92af commit af1bd7f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Expand Up @@ -13,3 +13,4 @@ export * from './useStorage'
export * from './useLifecycles'
export * from './useInterval'
export * from './useHash'
export * from './useHistory'
64 changes: 64 additions & 0 deletions src/useHistory.ts
@@ -0,0 +1,64 @@
import { reactive, toRefs, ToRefs, UnwrapRef } from 'vue'
import { useEvent } from './useEvent'
import { def } from './util'

type PathMethod = Extract<keyof History, 'replaceState' | 'pushState'>

function patchHistoryMethod(method: PathMethod): void {
const history = window.history
const origin = history[method]

def(
history,
method,
function (this: History, state: any) {
const result = origin.apply(this, (arguments as unknown) as Parameters<typeof origin>)
const event: any = new Event(method.toLowerCase())
event.state = state
window.dispatchEvent(event)
return result
},
true
)
}

patchHistoryMethod('pushState')
patchHistoryMethod('replaceState')

export interface IHistoryState {
state: any
hash: string
search: any
host: string
hostname: string
href: string
origin: string
pathname: string
port: string
protocol: string
}

function buildState(): IHistoryState {
const { state } = window.history
const { hash, search, host, hostname, href, origin, pathname, port, protocol } = window.location
return {
state,
hash,
search,
host,
hostname,
href,
origin,
pathname,
port,
protocol
}
}

export function useHistory(): ToRefs<IHistoryState> {
const state: UnwrapRef<IHistoryState> = reactive(buildState())
useEvent('popstate', buildState)
useEvent('pushstate' as any, buildState)
useEvent('replacestate' as any, buildState)
return toRefs(state)
}
8 changes: 8 additions & 0 deletions src/util.ts
@@ -0,0 +1,8 @@
export function def<T extends object>(obj: T, key: keyof T, val: any, enumerable?: boolean) {
Object.defineProperty(obj, key, {
value: val,
enumerable: !!enumerable,
writable: true,
configurable: true
})
}

0 comments on commit af1bd7f

Please sign in to comment.