Skip to content

Commit f419cb4

Browse files
authored
feat(b-img, b-img-lazy): add support for srcset and sizes props (closes #4348) (#4350)
1 parent f7087f0 commit f419cb4

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

src/components/image/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,28 @@ The default `blank-color` is `transparent`.
202202
- The `width` and `height` props will also apply the `width` and `height` attributes to the rendered
203203
`<img>` tag, even if `blank` is not set.
204204

205+
## `srcset` support
206+
207+
`<b-img>` supports the
208+
[`srcset` and `sizes` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-srcset)
209+
on images. The props accept either a string value, or an array of strings (the array of strings will
210+
be converted into a single string separated by commas).
211+
212+
For details on usage of these attributes, refer to
213+
[MDN's Responsive Images](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)
214+
guide.
215+
216+
**Notes:**
217+
218+
- If the `blank` prop is set, then `srcset` and `sizes` props are ignored
219+
- IE 11 does not support `srcset` and `sizes`, so ensure you have a value for the `src` prop
220+
- Vue-loader does not support project relative URLs (asset URLs) on the `srcset` attribute. Instead
221+
use `require(...)` to resolve the individual URL paths. Be cautious of creating a string of data
222+
URI's longer than supported by the maximum attribute value length of the browser. If your webpack
223+
config has a limit for the `url-loader` and you want to prevent inline data-urls, you may have to
224+
overwrite the loader limits: `require('!!url-loader?limit=0!./assets/photo.jpg')`
225+
- Support for `srcset` and `sizes` was added in release `2.1.0`
226+
205227
## Lazy loaded images
206228

207229
> Use our complementary `<b-img-lazy>` image component (based on `<b-img>`) to lazy load images as
@@ -288,4 +310,13 @@ removed.
288310
To force the final image to be shown, set the `show` prop to `true`. The `show` prop supports the
289311
Vue `.sync` modifier, and will be updated to `true` when the final image is shown.
290312

313+
### Lazy loaded `srcset` support
314+
315+
`<b-img-lazy>` supports setting the [`srcset` and `sizes`](#srcset-support) attributes on the
316+
rendered `<img>` element. These props will only be applied to the image once it has come into view.
317+
318+
See [`srcset` support](#srcset-support) above for prop usage details and limitations.
319+
320+
Support for `srcset` and `sizes` was added in release `2.1.0`.
321+
291322
<!-- Component reference added automatically from component package.json -->

src/components/image/img-lazy.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Vue from '../../utils/vue'
2+
import { concat } from '../../utils/array'
23
import { getComponentConfig } from '../../utils/config'
34
import { hasIntersectionObserverSupport } from '../../utils/env'
45
import { VBVisible } from '../../directives/visible/visible'
@@ -12,6 +13,14 @@ export const props = {
1213
default: null,
1314
required: true
1415
},
16+
srcset: {
17+
type: [String, Array],
18+
default: null
19+
},
20+
sizes: {
21+
type: [String, Array],
22+
default: null
23+
},
1524
alt: {
1625
type: String,
1726
default: null
@@ -109,6 +118,18 @@ export const BImgLazy = /*#__PURE__*/ Vue.extend({
109118
},
110119
computedHeight() {
111120
return this.isShown ? this.height : this.blankHeight || this.height
121+
},
122+
computedSrcset() {
123+
const srcset = concat(this.srcset)
124+
.filter(Boolean)
125+
.join(',')
126+
return !this.blankSrc || this.isShown ? srcset : null
127+
},
128+
computedSizes() {
129+
const sizes = concat(this.sizes)
130+
.filter(Boolean)
131+
.join(',')
132+
return !this.blankSrc || this.isShown ? sizes : null
112133
}
113134
},
114135
watch: {
@@ -173,6 +194,8 @@ export const BImgLazy = /*#__PURE__*/ Vue.extend({
173194
blank: this.computedBlank,
174195
width: this.computedWidth,
175196
height: this.computedHeight,
197+
srcset: this.computedSrcset || null,
198+
sizes: this.computedSizes || null,
176199
// Passthrough props
177200
alt: this.alt,
178201
blankColor: this.blankColor,

src/components/image/img.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Vue from '../../utils/vue'
22
import { mergeData } from 'vue-functional-data-merge'
3+
import { concat } from '../../utils/array'
34
import { getComponentConfig } from '../../utils/config'
45
import { isString } from '../../utils/inspect'
56

@@ -20,6 +21,14 @@ export const props = {
2021
type: String,
2122
default: null
2223
},
24+
srcset: {
25+
type: [String, Array],
26+
default: null
27+
},
28+
sizes: {
29+
type: [String, Array],
30+
default: null
31+
},
2332
alt: {
2433
type: String,
2534
default: null
@@ -106,6 +115,12 @@ export const BImg = /*#__PURE__*/ Vue.extend({
106115
let height = parseInt(props.height, 10) ? parseInt(props.height, 10) : null
107116
let align = null
108117
let block = props.block
118+
let srcset = concat(props.srcset)
119+
.filter(Boolean)
120+
.join(',')
121+
let sizes = concat(props.sizes)
122+
.filter(Boolean)
123+
.join(',')
109124
if (props.blank) {
110125
if (!height && Boolean(width)) {
111126
height = width
@@ -118,6 +133,9 @@ export const BImg = /*#__PURE__*/ Vue.extend({
118133
}
119134
// Make a blank SVG image
120135
src = makeBlankImgSrc(width, height, props.blankColor || 'transparent')
136+
// Disable srcset and sizes
137+
srcset = null
138+
sizes = null
121139
}
122140
if (props.left) {
123141
align = 'float-left'
@@ -134,7 +152,9 @@ export const BImg = /*#__PURE__*/ Vue.extend({
134152
src: src,
135153
alt: props.alt,
136154
width: width ? String(width) : null,
137-
height: height ? String(height) : null
155+
height: height ? String(height) : null,
156+
srcset: srcset || null,
157+
sizes: sizes || null
138158
},
139159
class: {
140160
'img-thumbnail': props.thumbnail,

src/components/image/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@
5555
{
5656
"prop": "right",
5757
"description": "Floats the image to the right when set"
58+
},
59+
{
60+
"prop": "srcset",
61+
"version": "2.1.0",
62+
"description": "One or more strings separated by commas (or an array of strings), indicating possible image sources for the user agent to use"
63+
},
64+
{
65+
"prop": "sizes",
66+
"version": "2.1.0",
67+
"description": "One or more strings separated by commas (or an array of strings), indicating a set of source sizes. Optionally used in combination with the srcset prop"
5868
}
5969
]
6070
},
@@ -124,6 +134,16 @@
124134
{
125135
"prop": "right",
126136
"description": "Floats the image to the right when set"
137+
},
138+
{
139+
"prop": "srcset",
140+
"version": "2.1.0",
141+
"description": "One or more strings separated by commas (or an array of strings), indicating possible image sources for the user agent to use"
142+
},
143+
{
144+
"prop": "sizes",
145+
"version": "2.1.0",
146+
"description": "One or more strings separated by commas (or an array of strings), indicating a set of source sizes. Optionally used in combination with the srcset prop"
127147
}
128148
]
129149
}

0 commit comments

Comments
 (0)