🌐 AI搜索 & 代理 主页
Skip to content

Commit 3f41c91

Browse files
authored
fix(b-link): default new <nuxt-link> prop prefetch to null for true tri-state prop (#5357)
Co-authored-by: Jacob Müller
1 parent 101faab commit 3f41c91

File tree

10 files changed

+110
-78
lines changed

10 files changed

+110
-78
lines changed

docs/common-props.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@
231231
"description": "router-link prop: Specify the event that triggers the link. In most cases you should leave this as the default"
232232
},
233233
"prefetch": {
234-
"description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'prefetch' to 'true' or 'false' will overwrite the default value of 'router.prefetchLinks'"
234+
"description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'prefetch' to 'true' or 'false' will overwrite the default value of 'router.prefetchLinks'",
235+
"version": "2.15.0"
235236
},
236237
"noPrefetch": {
237238
"description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'no-prefetch' will disabled this feature for the specific link"

docs/markdown/reference/router-links/README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,18 @@ additional Nuxt.js specific props.
158158
### `prefetch`
159159

160160
- type: `boolean`
161-
- default: `undefined`
162-
- availability: Nuxt.js 2.10.0+
161+
- default: `null`
162+
- availability: Nuxt.js 2.10.0+ and BootstrapVue 2.15.0+
163163

164164
To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within
165165
the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting `prefetch` to
166166
`true` or `false` will overwrite the default value of `router.prefetchLinks` configured in the
167167
`nuxt.config.js` configuration file.
168168

169-
**Note:** If you have are using a version of Nuxt.js `< 2.10.0`, then this prop will have no effect.
169+
**Notes:**
170+
171+
- If you have are using a version of Nuxt.js `< 2.10.0`, then this prop will have no effect.
172+
- Remember to `v-bind` the prop value (e.g. `:prefetch="true"` or `:prefetch="false"`).
170173

171174
Prefetching support requires
172175
[IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)

src/components/badge/badge.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import Vue from '../../utils/vue'
2+
import pluckProps from '../../utils/pluck-props'
23
import { mergeData } from 'vue-functional-data-merge'
34
import { getComponentConfig } from '../../utils/config'
4-
import pluckProps from '../../utils/pluck-props'
5-
import { BLink, propsFactory as linkPropsFactory } from '../link/link'
5+
import { clone } from '../../utils/object'
6+
import { BLink, props as BLinkProps } from '../link/link'
67

78
const NAME = 'BBadge'
89

9-
const linkProps = linkPropsFactory()
10+
const linkProps = clone(BLinkProps)
1011
delete linkProps.href.default
1112
delete linkProps.to.default
1213

1314
export const props = {
14-
...linkProps,
1515
tag: {
1616
type: String,
1717
default: 'span'
@@ -23,7 +23,8 @@ export const props = {
2323
pill: {
2424
type: Boolean,
2525
default: false
26-
}
26+
},
27+
...linkProps
2728
}
2829

2930
// @vue/component

src/components/breadcrumb/breadcrumb-link.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import Vue from '../../utils/vue'
22
import { mergeData } from 'vue-functional-data-merge'
33
import pluckProps from '../../utils/pluck-props'
44
import { htmlOrText } from '../../utils/html'
5-
import { BLink, propsFactory as linkPropsFactory } from '../link/link'
5+
import { BLink, props as BLinkProps } from '../link/link'
66

77
export const props = {
8-
...linkPropsFactory(),
98
text: {
109
type: String,
1110
default: null
@@ -17,7 +16,8 @@ export const props = {
1716
ariaCurrent: {
1817
type: String,
1918
default: 'location'
20-
}
19+
},
20+
...BLinkProps
2121
}
2222

2323
// @vue/component

src/components/button/button.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@ import { concat } from '../../utils/array'
66
import { getComponentConfig } from '../../utils/config'
77
import { addClass, removeClass } from '../../utils/dom'
88
import { isBoolean, isEvent, isFunction } from '../../utils/inspect'
9-
import { keys } from '../../utils/object'
9+
import { clone } from '../../utils/object'
1010
import { toString } from '../../utils/string'
11-
import { BLink, propsFactory as linkPropsFactory } from '../link/link'
11+
import { BLink, props as BLinkProps } from '../link/link'
1212

13-
// --- Constants --
13+
// --- Constants ---
1414

1515
const NAME = 'BButton'
1616

17+
// --- Props ---
18+
19+
const linkProps = clone(BLinkProps)
20+
delete linkProps.href.default
21+
delete linkProps.to.default
22+
1723
const btnProps = {
1824
block: {
1925
type: Boolean,
@@ -55,12 +61,7 @@ const btnProps = {
5561
}
5662
}
5763

58-
const linkProps = linkPropsFactory()
59-
delete linkProps.href.default
60-
delete linkProps.to.default
61-
const linkPropKeys = keys(linkProps)
62-
63-
export const props = { ...linkProps, ...btnProps }
64+
export const props = { ...btnProps, ...linkProps }
6465

6566
// --- Helper methods ---
6667

@@ -104,7 +105,7 @@ const computeClass = props => [
104105
]
105106

106107
// Compute the link props to pass to b-link (if required)
107-
const computeLinkProps = props => (isLink(props) ? pluckProps(linkPropKeys, props) : null)
108+
const computeLinkProps = props => (isLink(props) ? pluckProps(linkProps, props) : null)
108109

109110
// Compute the attributes for a button
110111
const computeAttrs = (props, data) => {
@@ -142,6 +143,7 @@ const computeAttrs = (props, data) => {
142143
}
143144
}
144145

146+
// --- Main component ---
145147
// @vue/component
146148
export const BButton = /*#__PURE__*/ Vue.extend({
147149
name: NAME,

src/components/dropdown/dropdown-item.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import Vue from '../../utils/vue'
22
import { requestAF } from '../../utils/dom'
3+
import { clone } from '../../utils/object'
34
import attrsMixin from '../../mixins/attrs'
45
import normalizeSlotMixin from '../../mixins/normalize-slot'
5-
import { BLink, propsFactory as linkPropsFactory } from '../link/link'
6+
import { BLink, props as BLinkProps } from '../link/link'
67

7-
export const props = linkPropsFactory()
8+
export const props = clone(BLinkProps)
89

910
// @vue/component
1011
export const BDropdownItem = /*#__PURE__*/ Vue.extend({

src/components/link/link.js

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,17 @@
11
import Vue from '../../utils/vue'
2+
import pluckProps from '../../utils/pluck-props'
23
import { concat } from '../../utils/array'
34
import { attemptBlur, attemptFocus } from '../../utils/dom'
4-
import { isEvent, isFunction, isUndefined } from '../../utils/inspect'
5+
import { isBoolean, isEvent, isFunction, isUndefined } from '../../utils/inspect'
56
import { computeHref, computeRel, computeTag, isRouterLink } from '../../utils/router'
6-
import { omit } from '../../utils/object'
77
import attrsMixin from '../../mixins/attrs'
88
import listenersMixin from '../../mixins/listeners'
99
import normalizeSlotMixin from '../../mixins/normalize-slot'
1010

11-
/**
12-
* The Link component is used in many other BV components
13-
* As such, sharing its props makes supporting all its features easier
14-
* However, some components need to modify the defaults for their own purpose
15-
* Prefer sharing a fresh copy of the props to ensure mutations
16-
* do not affect other component references to the props
17-
*
18-
* See: https://github.com/vuejs/vue-router/blob/dev/src/components/link.js
19-
*/
20-
export const propsFactory = () => ({
21-
href: {
22-
type: String,
23-
default: null
24-
},
25-
rel: {
26-
type: String,
27-
// Must be `null` if no value provided
28-
default: null
29-
},
30-
target: {
31-
type: String,
32-
default: '_self'
33-
},
34-
active: {
35-
type: Boolean,
36-
default: false
37-
},
38-
disabled: {
39-
type: Boolean,
40-
default: false
41-
},
42-
// <router-link> specific props
11+
// --- Props ---
12+
13+
// <router-link> specific props
14+
export const routerLinkProps = {
4315
to: {
4416
type: [String, Object],
4517
default: null
@@ -71,29 +43,61 @@ export const propsFactory = () => ({
7143
routerTag: {
7244
type: String,
7345
default: 'a'
74-
},
75-
// <nuxt-link> specific prop(s)
46+
}
47+
}
48+
49+
// <nuxt-link> specific props
50+
export const nuxtLinkProps = {
7651
prefetch: {
77-
type: Boolean
78-
// Must be `undefined` to fall back to the value defined in the
52+
type: Boolean,
53+
// Must be `null` to fall back to the value defined in the
7954
// `nuxt.config.js` configuration file for `router.prefetchLinks`
80-
// default: undefined
55+
// We convert `null` to `undefined`, so that Nuxt.js will use the
56+
// compiled default. Vue treats `undefined` as default of `false`
57+
// for Boolean props, so we must set it as `null` here to be a
58+
// true tri-state prop
59+
default: null
8160
},
8261
noPrefetch: {
8362
type: Boolean,
8463
default: false
8564
}
86-
})
65+
}
8766

88-
export const props = propsFactory()
67+
export const props = {
68+
href: {
69+
type: String,
70+
default: null
71+
},
72+
rel: {
73+
type: String,
74+
// Must be `null` if no value provided
75+
default: null
76+
},
77+
target: {
78+
type: String,
79+
default: '_self'
80+
},
81+
active: {
82+
type: Boolean,
83+
default: false
84+
},
85+
disabled: {
86+
type: Boolean,
87+
default: false
88+
},
89+
...routerLinkProps,
90+
...nuxtLinkProps
91+
}
8992

93+
// --- Main component ---
9094
// @vue/component
9195
export const BLink = /*#__PURE__*/ Vue.extend({
9296
name: 'BLink',
9397
// Mixin order is important!
9498
mixins: [attrsMixin, listenersMixin, normalizeSlotMixin],
9599
inheritAttrs: false,
96-
props: propsFactory(),
100+
props,
97101
computed: {
98102
computedTag() {
99103
// We don't pass `this` as the first arg as we need reactivity of the props
@@ -111,9 +115,16 @@ export const BLink = /*#__PURE__*/ Vue.extend({
111115
return computeHref({ to: this.to, href: this.href }, this.computedTag)
112116
},
113117
computedProps() {
114-
const props = this.isRouterLink ? { ...this.$props, tag: this.routerTag } : {}
115-
// Ensure the `href` prop does not exist for router links
116-
return this.computedHref ? props : omit(props, ['href'])
118+
const prefetch = this.prefetch
119+
return this.isRouterLink
120+
? {
121+
...pluckProps({ ...routerLinkProps, ...nuxtLinkProps }, this.$props),
122+
// Coerce `prefetch` value `null` to be `undefined`
123+
prefetch: isBoolean(prefetch) ? prefetch : undefined,
124+
// Pass `router-tag` as `tag` prop
125+
tag: this.routerTag
126+
}
127+
: {}
117128
},
118129
computedAttrs() {
119130
const {

src/components/list-group/list-group-item.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
2+
import Vue from '../../utils/vue'
33
import pluckProps from '../../utils/pluck-props'
44
import { arrayIncludes } from '../../utils/array'
55
import { getComponentConfig } from '../../utils/config'
6-
import { BLink, propsFactory as linkPropsFactory } from '../link/link'
6+
import { clone } from '../../utils/object'
7+
import { BLink, props as BLinkProps } from '../link/link'
8+
9+
// --- Constants ---
710

811
const NAME = 'BListGroupItem'
912

1013
const actionTags = ['a', 'router-link', 'button', 'b-link']
11-
const linkProps = linkPropsFactory()
14+
15+
// --- Props ---
16+
17+
const linkProps = clone(BLinkProps)
1218
delete linkProps.href.default
1319
delete linkProps.to.default
1420

@@ -31,6 +37,8 @@ export const props = {
3137
},
3238
...linkProps
3339
}
40+
41+
// --- Main component ---
3442
// @vue/component
3543
export const BListGroupItem = /*#__PURE__*/ Vue.extend({
3644
name: NAME,

src/components/nav/nav-item.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
3-
import { BLink, propsFactory as linkPropsFactory } from '../link/link'
2+
import Vue from '../../utils/vue'
3+
import { clone } from '../../utils/object'
4+
import { BLink, props as BLinkProps } from '../link/link'
5+
6+
// --- Props ---
47

5-
export const props = linkPropsFactory()
8+
export const props = clone(BLinkProps)
69

10+
// --- Main component ---
711
// @vue/component
812
export const BNavItem = /*#__PURE__*/ Vue.extend({
913
name: 'BNavItem',

src/components/navbar/navbar-brand.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
2+
import Vue from '../../utils/vue'
33
import pluckProps from '../../utils/pluck-props'
4-
import { BLink, propsFactory } from '../link/link'
4+
import { clone } from '../../utils/object'
5+
import { BLink, props as BLinkProps } from '../link/link'
56

6-
const linkProps = propsFactory()
7+
const linkProps = clone(BLinkProps)
78
linkProps.href.default = undefined
89
linkProps.to.default = undefined
910

0 commit comments

Comments
 (0)