11import { mergeData } from 'vue-functional-data-merge'
22
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- */
133export function propsFactory ( ) {
144 return {
15- href :String ,
5+ href : String ,
6+ text : String ,
167 rel : String ,
178 target : {
189 type : String ,
1910 default : '_self'
2011 } ,
12+ disabled : Boolean ,
2113 active : Boolean ,
14+
15+ //these are router-link component props (default active class changed)
2216 activeClass : {
2317 type : String ,
2418 default : 'active'
2519 } ,
2620 append : Boolean ,
27- disabled : Boolean ,
2821 event : {
2922 type : [ String , Array ] ,
3023 default : 'click'
@@ -45,59 +38,24 @@ export function propsFactory () {
4538
4639export const props = propsFactory ( )
4740
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'
7843}
7944
80- function clickHandlerFactory ( { disabled, tag, href, suppliedHandler, parent } ) {
81- const isRouterLink = tag === 'router-link'
82-
45+ function clickHandlerFactory ( { disabled, tag, href, suppliedHandler } ) {
8346 return function onClick ( e ) {
8447 if ( disabled && e instanceof Event ) {
8548 // Stop event from bubbling up.
8649 e . stopPropagation ( )
8750 // Kill the event loop attached to this specific EventTarget.
8851 e . stopImmediatePropagation ( )
8952 } else {
90- parent . $root . $emit ( 'clicked::link' , e )
91-
92- if ( isRouterLink && e . target . __vue__ ) {
93- e . target . __vue__ . $emit ( 'click' , e )
94- }
9553 if ( typeof suppliedHandler === 'function' ) {
9654 suppliedHandler ( ...arguments )
9755 }
9856 }
9957
100- if ( ( ! isRouterLink && href === '#' ) || disabled ) {
58+ if ( ( tag !== 'router-link' && href === '#' ) || disabled ) {
10159 // Stop scroll-to-top behavior or navigation.
10260 e . preventDefault ( )
10361 }
@@ -109,29 +67,38 @@ export default {
10967 name : 'CLink' ,
11068 props,
11169 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+
11574 const eventType = tag === 'router-link' ? 'nativeOn' : 'on'
11675 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+
11884 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+ } ,
12389 attrs : {
12490 rel,
12591 href,
12692 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
12995 } ,
96+ domProps,
13097 props : Object . assign ( props , { tag : props . routerTag } )
13198 } )
13299
133100 // 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' ) {
135102 delete componentData . attrs . href
136103 }
137104
0 commit comments