在前端显示图片时,一般满足这两个常见要求:
图片未加载时,先显示位图,加载后再显示实际图片。如果图片链接有问题(例如,404),位图仍会显示。你甚至可以添加点击图片并重新加载的功能。(比如知乎)但是,applet的原生组件image并不提供这些常见的功能。
注意:这里增加了2s的延迟。
小程序还没有启动自定义组件功能的时候,只能通过改变Page中的数据来显示底部位图,所以当时的处理方法非常痛苦。
因为我们需要知道这张图片的数据路径,所以我们必须给每张图片添加类似data-img-path的内容。
view wx : for=' { { obj . arr } } ' wx : key=' IMgsrc ' wx : for-item=' item ' wx : for-index=' ItemIdx ' image src=' { { item . IMgsrc } } Binderror=' on imageerror ' data-IMg-path=' obj . arr[{ { ItemIdx } }]。img src '/view/copy code const DEFAULT _ IMG='/assets/your _ DEFAULT _ img ' page({ data : { obj : { arr :[{ IMGsrc : ' your _ img 1 ' },{ imgSrc: 'your_img2' },],},},Magerror({ target 3: { dataset 3: { img path } }){ this。setdata({[img path]: default _ img,}}})复制代码
如果默认图片不一样怎么办?比如玩家、队伍、feed的默认图片一般都不一样。
通常,我们必须添加另一个属性,如data-img-type来标识默认图的类型。
!-团队地图-图像.data-img-type=' team'/!-玩家地图-图像.data-img-type=' player '/copy code const default _ img _ map={ feed 3360 '/assets/default _ feed ',team3360'/assets/default _ team ',player : '/assets/default _ player ',} Page({ data : { obj : { arr :[{ imgsrc 3: ' your _ img 1 ' },],}}setdata({[img path]: default _ img _ map[img type],})},})复制代码
g-4">1.3.图片在模板中页面层级浅倒还好,如果跨模板了,那么模板就可能要用一个类似于pathPrefix的属性来传递模板数据的路径前缀。
<!-- 球员排行模板 pathPrefix: String playerList: Array ...--><template name="srPlayerRank"> <view wx:for="{{ playerList }}" wx:key="imgSrc" wx:for-item="item" wx:for-index="itemIdx" > <image src="{{ item.imgSrc }}" binderror="onImageError" data-img-type="player" data-img-path="{{ pathPrefix }}.playerList[{{ itemIdx }}].imgSrc" /> </view></template>复制代码
最后在失败回调里调用setData({ [path]: DEFAULT_IMG })重新设置图片地址。
就问你蛋不蛋疼?这一坨data-img-path="{{ pathPrefix }}.playerList[{{ itemIdx }}].imgSrc"代码真让人无发可脱...
有了自定义组件后,用领袖【窃·格瓦拉】的话来说的话就是:“感觉好 door 了~”
原生写法一般要写4个文件:.json/.wxml/.js/.wxss
{%20%20%20%20"component":%20true}复制代码
<!--%20加载中的图片%20--><image%20%20%20%20hidden="{{%20!isLoading%20}}"%20%20%20%20src="{{%20errSrc%20}}"%20%20%20%20style="width:%20{{%20width%20}};%20height:%20{{%20height%20}};%20{{%20styleStr%20}}"%20%20%20%20mode="{{%20imgMode%20}}"/><!--%20实际加载的图片%20--><image%20%20%20%20hidden="{{%20isLoading%20}}"%20%20%20%20src="{{%20imgSrc%20||%20src%20}}"%20%20%20%20mode="{{%20imgMode%20}}"%20%20%20%20style="width:%20{{%20width%20}};%20height:%20{{%20height%20}};%20{{%20styleStr%20}}"%20%20%20%20bindload="_onImageLoad"%20%20%20%20binderror="_onImageError"%20%20%20%20lazy-load="{{%20true%20}}"/>复制代码
const%20DEFAULT_IMG%20=%20'/assets/your_default_img'Component({%20%20%20%20properties:%20{%20%20%20%20%20%20%20%20//%20图片地址%20%20%20%20%20%20%20%20src:%20String,%20%20%20%20%20%20%20%20//%20图片加载中,以及加载失败后的默认地址%20%20%20%20%20%20%20%20errSrc:%20{%20%20%20%20%20%20%20%20%20%20%20%20type:%20String,%20%20%20%20%20%20%20%20%20%20%20%20//%20默认是球队图标%20%20%20%20%20%20%20%20%20%20%20%20value:%20DEFAULT_IMG,%20%20%20%20%20%20%20%20},%20%20%20%20%20%20%20%20width:%20{%20%20%20%20%20%20%20%20%20%20%20%20type:%20String,%20%20%20%20%20%20%20%20%20%20%20%20value:%20'48rpx',%20%20%20%20%20%20%20%20},%20%20%20%20%20%20%20%20height:%20{%20%20%20%20%20%20%20%20%20%20%20%20type:%20String,%20%20%20%20%20%20%20%20%20%20%20%20value:%20'48rpx',%20%20%20%20%20%20%20%20},%20%20%20%20%20%20%20%20//%20样式字符串%20%20%20%20%20%20%20%20styleStr:%20{%20%20%20%20%20%20%20%20%20%20%20%20type:%20String,%20%20%20%20%20%20%20%20%20%20%20%20value:%20'',%20%20%20%20%20%20%20%20},%20%20%20%20%20%20%20%20//%20图片裁剪、缩放的模式(详见文档)%20%20%20%20%20%20%20%20imgMode:%20{%20%20%20%20%20%20%20%20%20%20%20%20type:%20String,%20%20%20%20%20%20%20%20%20%20%20%20value:%20'scaleToFill',%20%20%20%20%20%20%20%20},%20%20%20%20},%20%20%20%20data:%20{%20%20%20%20%20%20%20%20imgSrc:%20'',%20%20%20%20%20%20%20%20isLoading:%20true,%20%20%20%20},%20%20%20%20methods:%20{%20%20%20%20%20%20%20%20//%20加载图片出错%20%20%20%20%20%20%20%20_onImageError%20(e)%20{%20%20%20%20%20%20%20%20%20%20%20%20this.setData({%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20imgSrc:%20this.data.errSrc,%20%20%20%20%20%20%20%20%20%20%20%20})%20%20%20%20%20%20%20%20%20%20%20%20this.triggerEvent('onImageError',%20e)%20%20%20%20%20%20%20%20},%20%20%20%20%20%20%20%20//%20加载图片完毕%20%20%20%20%20%20%20%20_onImageLoad%20(e)%20{%20%20%20%20%20%20%20%20%20%20%20%20this.setData({%20isLoading:%20false%20})%20%20%20%20%20%20%20%20%20%20%20%20this.triggerEvent('onImageLoad',%20e)%20%20%20%20%20%20%20%20},%20%20%20%20},})复制代码
布吉岛大家使用原生写法时有木有一些感觉不方便的地方:
所以以下是一个使用单文件组件封装原生%20image%20组件的例子。
<config>{%20%20%20%20"component":%20true}</config><template%20lang="wxml">%20%20%20%20<!--%20加载中的图片%20-->%20%20%20%20<image%20%20%20%20%20%20%20%20hidden="{{%20!isLoading%20}}"%20%20%20%20%20%20%20%20src="{{%20errSrc%20}}"%20%20%20%20%20%20%20%20style="{{%20imgStyleStr%20}}"%20%20%20%20%20%20%20%20mode="{{%20imgMode%20}}"%20%20%20%20/>%20%20%20%20<!--%20实际加载的图片%20-->%20%20%20%20<image%20%20%20%20%20%20%20%20hidden="{{%20isLoading%20}}"%20%20%20%20%20%20%20%20src="{{%20imgSrc%20||%20src%20}}"%20%20%20%20%20%20%20%20mode="{{%20imgMode%20}}"%20%20%20%20%20%20%20%20style="{{%20imgStyleStr%20}}"%20%20%20%20%20%20%20%20bindload="_onImageLoad"%20%20%20%20%20%20%20%20binderror="_onImageError"%20%20%20%20%20%20%20%20lazy-load="{{%20true%20}}"%20%20%20%20/></template><script>/**%20*%20图片组件,能够传递备用图片以防图片失效%20*%20https://developers.weixin.qq.com/miniprogram/dev/component/image.html%20*///%20也可以设置为网络图片如:%20https://foo/bar.pngconst DEFAULT_IMG = '/assets/your_default_img'export default { props: { // 图片地址 src: String, // 图片加载中,以及加载失败后的默认地址 errSrc: { type: String, // 默认是球队图标 default: DEFAULT_IMG, }, width: { type: String, default: '48rpx', }, height: { type: String, default: '48rpx', }, // 样式字符串 styleStr: { type: String, default: '', }, // 图片裁剪、缩放的模式(详见文档) imgMode: { type: String, default: 'scaleToFill', }, }, data () { return { imgSrc: '', isLoading: true, } }, computed: { // 样式字符串 imgStyleStr () { return `width: ${this.width}; height: ${this.height}; ${this.styleStr}` }, }, methods: { // 加载图片出错 _onImageError (e) { this.imgSrc = this.errSrc this.$emit('onImageError', e) }, // 加载图片完毕 _onImageLoad (e) { this.isLoading = false this.$emit('onImageLoad', e) }, },}</script><style lang="scss"></style>