-
-
Notifications
You must be signed in to change notification settings - Fork 5k
/
Copy pathguards.js
80 lines (67 loc) · 1.98 KB
/
guards.js
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
73
74
75
76
77
78
79
80
import { getCurrentInstance, onUnmounted, onActivated, onDeactivated } from 'vue'
import { throwNoCurrentInstance } from './utils'
import { useRouter } from './globals'
export function onBeforeRouteUpdate (guard) {
if (process.env.NODE_ENV !== 'production') {
throwNoCurrentInstance('onBeforeRouteUpdate')
}
return useFilteredGuard(guard, isUpdateNavigation)
}
function isUpdateNavigation (to, from, depth) {
const toMatched = to.matched
const fromMatched = from.matched
return (
toMatched.length >= depth &&
toMatched
.slice(0, depth + 1)
.every((record, i) => record === fromMatched[i])
)
}
function isLeaveNavigation (to, from, depth) {
const toMatched = to.matched
const fromMatched = from.matched
return toMatched.length < depth || toMatched[depth] !== fromMatched[depth]
}
export function onBeforeRouteLeave (guard) {
if (process.env.NODE_ENV !== 'production') {
throwNoCurrentInstance('onBeforeRouteLeave')
}
return useFilteredGuard(guard, isLeaveNavigation)
}
function registerGuard (router, guard, fn, depth) {
return router.beforeEach((to, from, next) =>
fn(to, from, depth) ? guard(to, from, next) : next()
)
}
const noop = () => {}
function useFilteredGuard (guard, fn) {
const instance = getCurrentInstance()
const router = useRouter()
let target = instance.proxy
// find the nearest RouterView to know the depth
while (
target &&
target.$vnode &&
target.$vnode.data &&
target.$vnode.data.routerViewDepth == null
) {
target = target.$parent
}
const depth =
target && target.$vnode && target.$vnode.data
? target.$vnode.data.routerViewDepth
: null
if (depth != null) {
let removeGuard = registerGuard(router, guard, fn, depth)
onUnmounted(removeGuard)
onActivated(() => {
removeGuard = removeGuard || registerGuard(router, guard, fn, depth)
})
onDeactivated(() => {
removeGuard()
removeGuard = null
})
return removeGuard
}
return noop
}