Skip to content

Commit

Permalink
Image: fix ssr and object-fit compatibility. (#15346)
Browse files Browse the repository at this point in the history
* fix: Image is not defined during ssr

Delay loadImage to mounted hook and add $isServer check

* fix(image): simulate object-fit behavior to compatible with IE11 and other browsers which not suppor

fix #15278

* fix: image inline-flex with overflow will still extend its parent element
  • Loading branch information
SimonaliaChen authored and island205 committed May 7, 2019
1 parent 06dfe16 commit 340da2f
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 13 deletions.
89 changes: 76 additions & 13 deletions packages/image/src/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
class="el-image__inner"
:src="src"
:alt="alt"
:style="{ 'object-fit': fit }">
:style="imageStyle"
:class="{ 'el-image__inner--center': alignCenter }">
</div>
</template>

Expand All @@ -21,6 +22,16 @@
import { isString, isHtmlElement } from 'element-ui/src/utils/types';
import throttle from 'throttle-debounce/throttle';
const isSupportObjectFit = () => document.documentElement.style.objectFit !== undefined;
const ObjectFit = {
NONE: 'none',
CONTAIN: 'contain',
COVER: 'cover',
FILL: 'fill',
SCALE_DOWN: 'scale-down'
};
export default {
name: 'ElImage',
Expand All @@ -38,42 +49,64 @@
return {
loading: true,
error: false,
show: !this.lazy
show: !this.lazy,
imageWidth: 0,
imageHeight: 0
};
},
computed: {
imageStyle() {
const { fit } = this;
if (!this.$isServer && fit) {
return isSupportObjectFit()
? { 'object-fit': fit }
: this.getImageStyle(fit);
}
return {};
},
alignCenter() {
return !this.$isServer && !isSupportObjectFit() && this.fit !== ObjectFit.FILL;
}
},
watch: {
src: {
handler(val) {
this.show && this.loadImage(val);
},
immediate: true
src(val) {
this.show && this.loadImage();
},
show(val) {
val && this.loadImage(this.src);
val && this.loadImage();
}
},
mounted() {
this.lazy && this.addLazyLoadListener();
if (this.lazy) {
this.addLazyLoadListener();
} else {
this.loadImage();
}
},
beforeDestroy() {
this.lazy && this.removeLazyLoadListener();
},
methods: {
loadImage(val) {
loadImage() {
if (this.$isServer) return;
// reset status
this.loading = true;
this.error = false;
const img = new Image();
img.onload = this.handleLoad.bind(this);
img.onload = e => this.handleLoad(e, img);
img.onerror = this.handleError.bind(this);
img.src = val;
img.src = this.src;
},
handleLoad(e) {
handleLoad(e, img) {
this.imageWidth = img.width;
this.imageHeight = img.height;
this.loading = false;
this.$emit('load', e);
},
Expand Down Expand Up @@ -117,6 +150,36 @@
off(_scrollContainer, 'scroll', _lazyLoadHandler);
this._scrollContainer = null;
this._lazyLoadHandler = null;
},
/**
* simulate object-fit behavior to compatible with IE11 and other browsers which not support object-fit
*/
getImageStyle(fit) {
const { imageWidth, imageHeight } = this;
const {
clientWidth: containerWidth,
clientHeight: containerHeight
} = this.$el;
if (!imageWidth || !imageHeight || !containerWidth || !containerHeight) return {};
const vertical = imageWidth / imageHeight < 1;
if (fit === ObjectFit.SCALE_DOWN) {
const isSmaller = imageWidth < containerWidth && imageHeight < containerHeight;
fit = isSmaller ? ObjectFit.NONE : ObjectFit.CONTAIN;
}
switch (fit) {
case ObjectFit.NONE:
return { width: 'auto', height: 'auto' };
case ObjectFit.CONTAIN:
return vertical ? { width: 'auto' } : { height: 'auto' };
case ObjectFit.COVER:
return vertical ? { height: 'auto' } : { width: 'auto' };
default:
return {};
}
}
}
};
Expand Down
10 changes: 10 additions & 0 deletions packages/theme-chalk/src/image.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@
}

@include b(image) {
position: relative;
display: inline-block;
overflow: hidden;

@include e(inner) {
@extend %size;
vertical-align: top;

@include m(center) {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
}
}

@include e(placeholder) {
Expand Down

0 comments on commit 340da2f

Please sign in to comment.