1
1
import { mergeData } from 'vue-functional-data-merge'
2
2
3
- /**
4
- * The Link component is used in many other BV components.
5
- * As such, sharing its props makes supporting all its features easier.
6
- * However, some components need to modify the defaults for their own purpose.
7
- * Prefer sharing a fresh copy of the props to ensure mutations
8
- * do not affect other component references to the props.
9
- *
10
- * https://github.com/vuejs/vue-router/blob/dev/src/components/link.js
11
- * @return {{} }
12
- */
13
3
export function propsFactory ( ) {
14
4
return {
15
- href :String ,
5
+ href : String ,
6
+ text : String ,
16
7
rel : String ,
17
8
target : {
18
9
type : String ,
19
10
default : '_self'
20
11
} ,
12
+ disabled : Boolean ,
21
13
active : Boolean ,
14
+
15
+ //these are router-link component props (default active class changed)
22
16
activeClass : {
23
17
type : String ,
24
18
default : 'active'
25
19
} ,
26
20
append : Boolean ,
27
- disabled : Boolean ,
28
21
event : {
29
22
type : [ String , Array ] ,
30
23
default : 'click'
@@ -45,59 +38,24 @@ export function propsFactory () {
45
38
46
39
export const props = propsFactory ( )
47
40
48
- function computeTag ( props , parent ) {
49
- return Boolean ( parent . $router ) && props . to && ! props . disabled ? 'router-link' : 'a'
50
- }
51
-
52
- /*eslint no-unused-vars: ["error", {"args": "none"}]*/
53
- function computeHref ( { disabled, href, to } , tag ) {
54
- // We've already checked the parent.$router in computeTag,
55
- // so router-link means live router.
56
- // When deferring to Vue Router's router-link,
57
- // don't use the href attr at all.
58
- // Must return undefined for router-link to populate href.
59
- if ( tag === 'router-link' ) return void 0
60
- // If href explicitly provided
61
- if ( href ) return href
62
- // Reconstruct href when `to` used, but no router
63
- if ( to ) {
64
- // Fallback to `to` prop (if `to` is a string)
65
- if ( typeof to === 'string' ) return to
66
- // Fallback to `to.path` prop (if `to` is an object)
67
- if ( typeof to === 'object' && typeof to . path === 'string' ) return to . path
68
- }
69
- // If nothing is provided use '#'
70
- return '#'
71
- }
72
-
73
- function computeRel ( { target, rel } ) {
74
- if ( target === '_blank' && rel === null ) {
75
- return 'noopener'
76
- }
77
- return rel || null
41
+ function getComputedTag ( { to, disabled} , parent ) {
42
+ return Boolean ( parent . $router ) && to && ! disabled ? 'router-link' : 'a'
78
43
}
79
44
80
- function clickHandlerFactory ( { disabled, tag, href, suppliedHandler, parent } ) {
81
- const isRouterLink = tag === 'router-link'
82
-
45
+ function clickHandlerFactory ( { disabled, tag, href, suppliedHandler } ) {
83
46
return function onClick ( e ) {
84
47
if ( disabled && e instanceof Event ) {
85
48
// Stop event from bubbling up.
86
49
e . stopPropagation ( )
87
50
// Kill the event loop attached to this specific EventTarget.
88
51
e . stopImmediatePropagation ( )
89
52
} else {
90
- parent . $root . $emit ( 'clicked::link' , e )
91
-
92
- if ( isRouterLink && e . target . __vue__ ) {
93
- e . target . __vue__ . $emit ( 'click' , e )
94
- }
95
53
if ( typeof suppliedHandler === 'function' ) {
96
54
suppliedHandler ( ...arguments )
97
55
}
98
56
}
99
57
100
- if ( ( ! isRouterLink && href === '#' ) || disabled ) {
58
+ if ( ( tag !== 'router-link' && href === '#' ) || disabled ) {
101
59
// Stop scroll-to-top behavior or navigation.
102
60
e . preventDefault ( )
103
61
}
@@ -109,29 +67,38 @@ export default {
109
67
name : 'CLink' ,
110
68
props,
111
69
render ( h , { props, data, parent, children } ) {
112
- const tag = computeTag ( props , parent )
113
- const rel = computeRel ( props )
114
- const href = computeHref ( props , tag )
70
+ const tag = getComputedTag ( props , parent )
71
+ const rel = props . target === '_blank' && ! props . rel ? 'noopener' : props . rel
72
+ const href = props . href || '#'
73
+
115
74
const eventType = tag === 'router-link' ? 'nativeOn' : 'on'
116
75
const suppliedHandler = ( data [ eventType ] || { } ) . click
117
- const handlers = { click : clickHandlerFactory ( { tag, href, disabled : props . disabled , suppliedHandler, parent } ) }
76
+ const handlers = { click : clickHandlerFactory (
77
+ { tag, href, disabled : props . disabled , suppliedHandler }
78
+ ) }
79
+
80
+ const tabindex = data . attrs ? data . attrs . tabindex : null
81
+
82
+ const domProps = props . text ? { innerHTML : props . text } : null
83
+
118
84
const componentData = mergeData ( data , {
119
- class : [
120
- props . active ? ( props . exact ? props . exactActiveClass : props . activeClass ) : null ,
121
- { disabled : props . disabled }
122
- ] ,
85
+ class : {
86
+ disabled : props . disabled ,
87
+ 'active' : props . active
88
+ } ,
123
89
attrs : {
124
90
rel,
125
91
href,
126
92
target : props . target ,
127
- tabindex : props . disabled ? '-1' : ( data . attrs ? data . attrs . tabindex : null ) ,
128
- 'aria-disabled' : ( tag === 'a' && props . disabled ) ? 'true' : null
93
+ tabindex : props . disabled ? '-1' : tabindex ,
94
+ 'aria-disabled' : tag === 'a' && props . disabled ? 'true' : null
129
95
} ,
96
+ domProps,
130
97
props : Object . assign ( props , { tag : props . routerTag } )
131
98
} )
132
99
133
100
// If href prop exists on router-link (even undefined or null) it fails working on SSR
134
- if ( ! componentData . attrs . href ) {
101
+ if ( tag === 'router-link' ) {
135
102
delete componentData . attrs . href
136
103
}
137
104
0 commit comments