提交 997964b5 编写于 作者: chenli_1989's avatar chenli_1989

fix: 修复 image 组件 contentPath 字段默认为空导致 img 请求空问题

上级 be1b23b8
<template> <template>
<uni-image v-on="$listeners"> <uni-image v-on="$listeners">
<div <div
ref="content" ref="content"
:style="style" :style="style"
/> />
<img :src="contentPath"> <img
<v-uni-resize-sensor v-if="contentPath"
v-if="mode === 'widthFix' || mode === 'heightFix'" :src="contentPath"
ref="sensor" >
@resize="_fixSize()" <v-uni-resize-sensor
/> v-if="mode === 'widthFix' || mode === 'heightFix'"
</uni-image> ref="sensor"
</template> @resize="_fixSize()"
<script> />
function fixNumber (number) { </uni-image>
// fix: 解决 Chrome 浏览器上某些情况下导致 1px 缝隙的问题 </template>
if (typeof navigator && navigator.vendor === 'Google Inc.' && number > 10) { <script>
number = Math.round(number / 2) * 2 function fixNumber (number) {
} // fix: 解决 Chrome 浏览器上某些情况下导致 1px 缝隙的问题
return number if (typeof navigator && navigator.vendor === 'Google Inc.' && number > 10) {
} number = Math.round(number / 2) * 2
}
export default { return number
name: 'Image', }
props: {
src: { export default {
type: String, name: 'Image',
default: '' props: {
}, src: {
mode: { type: String,
type: String, default: ''
default: 'scaleToFill' },
}, mode: {
// TODO 懒加载 type: String,
lazyLoad: { default: 'scaleToFill'
type: [Boolean, String], },
default: false // TODO 懒加载
} lazyLoad: {
}, type: [Boolean, String],
data () { default: false
return { }
originalWidth: 0, },
originalHeight: 0, data () {
originalStyle: { width: '', height: '' }, return {
contentPath: '' originalWidth: 0,
} originalHeight: 0,
}, originalStyle: { width: '', height: '' },
computed: { contentPath: ''
ratio () { }
return this.originalWidth && this.originalHeight ? this.originalWidth / this.originalHeight : 0 },
}, computed: {
style () { ratio () {
let size = 'auto' return this.originalWidth && this.originalHeight ? this.originalWidth / this.originalHeight : 0
let position = '' },
const repeat = 'no-repeat' style () {
let size = 'auto'
switch (this.mode) { let position = ''
case 'aspectFit': const repeat = 'no-repeat'
size = 'contain'
position = 'center center' switch (this.mode) {
break case 'aspectFit':
case 'aspectFill': size = 'contain'
size = 'cover' position = 'center center'
position = 'center center' break
break case 'aspectFill':
case 'widthFix': size = 'cover'
case 'heightFix': position = 'center center'
size = '100% 100%' break
break case 'widthFix':
case 'top': case 'heightFix':
position = 'center top' size = '100% 100%'
break break
case 'bottom': case 'top':
position = 'center bottom' position = 'center top'
break break
case 'center': case 'bottom':
position = 'center center' position = 'center bottom'
break break
case 'left': case 'center':
position = 'left center' position = 'center center'
break break
case 'right': case 'left':
position = 'right center' position = 'left center'
break break
case 'top left': case 'right':
position = 'left top' position = 'right center'
break break
case 'top right': case 'top left':
position = 'right top' position = 'left top'
break break
case 'bottom left': case 'top right':
position = 'left bottom' position = 'right top'
break break
case 'bottom right': case 'bottom left':
position = 'right bottom' position = 'left bottom'
break break
default: case 'bottom right':
size = '100% 100%' position = 'right bottom'
position = '0% 0%' break
break default:
} size = '100% 100%'
position = '0% 0%'
return { break
'background-image': this.contentPath ? `url("${this.contentPath}")` : 'none', }
'background-position': position,
'background-size': size, return {
'background-repeat': repeat 'background-image': this.contentPath ? `url("${this.contentPath}")` : 'none',
} 'background-position': position,
} 'background-size': size,
}, 'background-repeat': repeat
watch: { }
src (newValue, oldValue) { }
this._loadImage() },
}, watch: {
mode (newValue, oldValue) { src (newValue, oldValue) {
if (oldValue === 'widthFix' || oldValue === 'heightFix') { this._loadImage()
this._resetSize() },
} mode (newValue, oldValue) {
if (newValue === 'widthFix' || newValue === 'heightFix') { if (oldValue === 'widthFix' || oldValue === 'heightFix') {
this._fixSize() this._resetSize()
} }
} if (newValue === 'widthFix' || newValue === 'heightFix') {
}, this._fixSize()
mounted () { }
this.originalStyle.width = this.$el.style.width || '' }
this.originalStyle.height = this.$el.style.height || '' },
this._loadImage() mounted () {
}, this.originalStyle.width = this.$el.style.width || ''
beforeDestroy () { this.originalStyle.height = this.$el.style.height || ''
this._clearImage() this._loadImage()
}, },
methods: { beforeDestroy () {
_fixSize () { this._clearImage()
if (this.ratio) { },
const $el = this.$el methods: {
const rect = $el.getBoundingClientRect() _fixSize () {
if (this.mode === 'widthFix') { if (this.ratio) {
const width = rect.width const $el = this.$el
if (width) { const rect = $el.getBoundingClientRect()
$el.style.height = fixNumber(width / this.ratio) + 'px' if (this.mode === 'widthFix') {
} const width = rect.width
} else if (this.mode === 'heightFix') { if (width) {
const height = rect.height $el.style.height = fixNumber(width / this.ratio) + 'px'
if (height) { }
$el.style.width = fixNumber(height * this.ratio) + 'px' } else if (this.mode === 'heightFix') {
} const height = rect.height
} if (height) {
} $el.style.width = fixNumber(height * this.ratio) + 'px'
}, }
_resetSize () { }
this.$el.style.width = this.originalStyle.width }
this.$el.style.height = this.originalStyle.height },
}, _resetSize () {
_resetData () { this.$el.style.width = this.originalStyle.width
this.originalWidth = 0 this.$el.style.height = this.originalStyle.height
this.originalHeight = 0 },
this.contentPath = '' _resetData () {
}, this.originalWidth = 0
_loadImage () { this.originalHeight = 0
const realImagePath = this.$getRealPath(this.src) this.contentPath = ''
if (realImagePath) { },
const img = this._img = this._img || new Image() _loadImage () {
img.onload = $event => { const realImagePath = this.$getRealPath(this.src)
this._img = null if (realImagePath) {
this.originalWidth = img.width const img = this._img = this._img || new Image()
this.originalHeight = img.height img.onload = $event => {
this._img = null
this._fixSize() this.originalWidth = img.width
this.originalHeight = img.height
this.contentPath = realImagePath
this._fixSize()
this.$trigger('load', $event, {
width: img.width, this.contentPath = realImagePath
height: img.height
}) this.$trigger('load', $event, {
} width: img.width,
img.onerror = $event => { height: img.height
this._img = null })
this._resetData() }
// 与微信小程序保持一致,保留之前样式 img.onerror = $event => {
// this._resetSize() this._img = null
this.$trigger('error', $event, { this._resetData()
errMsg: `GET ${this.src} 404 (Not Found)` // 与微信小程序保持一致,保留之前样式
}) // this._resetSize()
} this.$trigger('error', $event, {
img.src = realImagePath errMsg: `GET ${this.src} 404 (Not Found)`
} else { })
this._clearImage() }
// 与微信小程序保持一致,保留之前样式 img.src = realImagePath
// this._resetData() } else {
this._resetSize() this._clearImage()
} // 与微信小程序保持一致,保留之前样式
}, // this._resetData()
_clearImage () { this._resetSize()
const img = this._img }
if (img) { },
img.onload = null _clearImage () {
img.onerror = null const img = this._img
this._img = null if (img) {
} img.onload = null
} img.onerror = null
} this._img = null
} }
</script> }
<style> }
uni-image { }
width: 320px; </script>
height: 240px; <style>
display: inline-block; uni-image {
overflow: hidden; width: 320px;
position: relative; height: 240px;
} display: inline-block;
overflow: hidden;
uni-image[hidden] { position: relative;
display: none; }
}
uni-image[hidden] {
uni-image > div { display: none;
width: 100%; }
height: 100%;
} uni-image > div {
width: 100%;
uni-image > img { height: 100%;
-webkit-touch-callout: none; }
-webkit-user-select: none;
-moz-user-select: none; uni-image > img {
display: block; -webkit-touch-callout: none;
position: absolute; -webkit-user-select: none;
top: 0; -moz-user-select: none;
left: 0; display: block;
width: 100%; position: absolute;
height: 100%; top: 0;
opacity: 0; left: 0;
} width: 100%;
height: 100%;
uni-image > .uni-image-will-change { opacity: 0;
will-change: transform; }
}
</style> uni-image > .uni-image-will-change {
will-change: transform;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册