零、问题的由来

一般在前端展示图片时都会碰到这两个常见的需求:

图片未加载完成时先展示占位图,等到图片加载完毕后再展示实际的图片。

假如图片链接有问题(比如 404),依然展示占位图。甚至你还可以增加点击图片再次加载的功能。(例如知乎)

然鹅,小程序原生组件 image 并没有提供这些常用功能...

注:这里加了 2s 的延迟

一、常规操作

在小程序没还没推出自定义组件功能时,只能通过改变 Page 中的 data 来展示兜底的占位图,所以当时的处理方式十分蛋疼...

1.1.相同默认图

由于需要知道这个图片的数据路径,所以不得不在每个 image 上加上类似 data-img-path 的东西。

wx:for="{{ obj.arr }}"

wx:key="imgSrc"

wx:for-item="item"

wx:for-index="itemIdx"

>

src="{{ item.imgSrc }}"

binderror="onImageError"

data-img-path="obj.arr[{{ itemIdx }}].imgSrc"

/>

const DEFAULT_IMG = '/assets/your_default_img'

Page({

data: {

obj: {

arr: [

{ imgSrc: 'your_img1' },

{ imgSrc: 'your_img2' },

],

},

},

onImageError ({

target: { dataset: { imgPath } },

}) {

this.setData({

[imgPath]: DEFAULT_IMG,

})

},

})

1.2.不同默认图

如果默认图片不同呢?例如球员、球队和 feed 的默认图片一般都是不同的。

那么一般只好再增加一个属性例如 data-img-type 来标识默认图的类型。

...

data-img-type="team"

/>

...

data-img-type="player"

/>

const DEFAULT_IMG_MAP = {

feed: '/assets/default_feed',

team: '/assets/default_team',

player: '/assets/default_player',

}

Page({

data: {

obj: {

arr: [

{ imgSrc: 'your_img1' },

{ imgSrc: 'your_img2' },

],

},

},

onImageError ({

target: { dataset: { imgPath, imgType } },

}) {

this.setData({

[imgPath]: DEFAULT_IMG_MAP[imgType],

})

},

})

1.3.图片在模板中

页面层级浅倒还好,如果跨模板了,那么模板就可能要用一个类似于 pathPrefix 的属性来传递模板数据的路径前缀。

wx:for="{{ playerList }}"

wx:key="imgSrc"

wx:for-item="item"

wx:for-index="itemIdx"

>

src="{{ item.imgSrc }}"

binderror="onImageError"

data-img-type="player"

data-img-path="{{ pathPrefix }}.playerList[{{ itemIdx }}].imgSrc"

/>

最后在失败回调里调用 setData({ [path]: DEFAULT_IMG }) 重新设置图片地址。

就问你蛋不蛋疼?这一坨 data-img-path="{{ pathPrefix }}.playerList[{{ itemIdx }}].imgSrc" 代码真让人无发可脱...

二、自定义组件

有了自定义组件后,用领袖【窃·格瓦拉】的话来说的话就是:“感觉好 door 了~”

2.1.原生自定义组件

原生写法一般要写4个文件:.json/.wxml/.js/.wxss

TuaImage.json

{

"component": true

}

TuaImage.wxml

hidden="{{ !isLoading }}"

src="{{ errSrc }}"

style="width: {{ width }}; height: {{ height }}; {{ styleStr }}"

mode="{{ imgMode }}"

/>

hidden="{{ isLoading }}"

src="{{ imgSrc || src }}"

mode="{{ imgMode }}"

style="width: {{ width }}; height: {{ height }}; {{ styleStr }}"

bindload="_onImageLoad"

binderror="_onImageError"

lazy-load="{{ true }}"

/>

TuaImage.js

const DEFAULT_IMG = '/assets/your_default_img'

Component({

properties: {

// 图片地址

src: String,

// 图片加载中,以及加载失败后的默认地址

errSrc: {

type: String,

// 默认是球队图标

value: DEFAULT_IMG,

},

width: {

type: String,

value: '48rpx',

},

height: {

type: String,

value: '48rpx',

},

// 样式字符串

styleStr: {

type: String,

value: '',

},

// 图片裁剪、缩放的模式(详见文档)

imgMode: {

type: String,

value: 'scaleToFill',

},

},

data: {

imgSrc: '',

isLoading: true,

},

methods: {

// 加载图片出错

_onImageError (e) {

this.setData({

imgSrc: this.data.errSrc,

})

this.triggerEvent('onImageError', e)

},

// 加载图片完毕

_onImageLoad (e) {

this.setData({ isLoading: false })

this.triggerEvent('onImageLoad', e)

},

},

})

布吉岛大家使用原生写法时有木有一些感觉不方便的地方:

4个文件:.json/.wxml/.js/.wxss,这样老需要切来切去的降低效率

properties 是什么鬼?大家(React/Vue)一般不都用 props 么?

style="width: {{ width }}; height: {{ height }}; {{ styleStr }}" 样式字符串怎么辣么长...

2.2.TuaImage.vue

所以以下是一个使用单文件组件封装原生 image 组件的例子。

使用单文件组件将配置、模板、脚本、样式写在一个文件中,方便维护。

使用计算属性 computed 将样式字符串写在 js 中。

使用 this.imgSrc = this.errSrc 而不是 this.setData 来改变 data。

{

"component": true

}

hidden="{{ !isLoading }}"

src="{{ errSrc }}"

style="{{ imgStyleStr }}"

mode="{{ imgMode }}"

/>

hidden="{{ isLoading }}"

src="{{ imgSrc || src }}"

mode="{{ imgMode }}"

style="{{ imgStyleStr }}"

bindload="_onImageLoad"

binderror="_onImageError"

lazy-load="{{ true }}"

/>

/**

* 图片组件,能够传递备用图片以防图片失效

* https://developers.weixin.qq.com/miniprogram/dev/component/image.html

*/

// 也可以设置为网络图片如: https://foo/bar.png

const 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)

},

},

}

采用框架是 tua-mp:

相关文章:

php 小程序自定义图,微信小程序之如何使用自定义组件封装原生 image 组件相关推荐

  1. 笑话与趣图微信小程序源码_带广告流量主

    笑话与趣图微信小程序源码_带流量主-PHP文档类资源-CSDN下载这是一款以笑话和趣味图为主的一款微信小程序源码更多下载资源.学习资料请访问CSDN下载频道.https://download.csdn ...

  2. Wuss Weapp一款高质量,组件齐全,高自定义的微信小程序 UI 组件库

    Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库 文档 https://phonycode.github.io/wuss-weapp 扫码体验 使用微信扫一扫体验小程序组 ...

  3. Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库

    Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库 文档 https://phonycode.github.io/wuss-weapp 扫码体验 使用微信扫一扫体验小程序组 ...

  4. [转]微信小程序之购物车 —— 微信小程序实战商城系列(5)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70755892 续上一篇的文章:微信小程序之商品属性分类  -- 微信小程序实战商城 ...

  5. 微信群打卡小程序_用微信小程序“小打卡”,打造免费的阅读平台!

    小归 一直和微信小程序--"小打卡"的创始人保持着微信通讯,也写了<快捷|以"小打卡"为例带你玩转微信小程序!>,这篇文章主要是真对如何打卡来写的, ...

  6. 微信小程序的文件结构 —— 微信小程序教程系列(1)

    文件结构 示例目录:HelloWorld *******************************************************分割线********************* ...

  7. 微信小程序之目前为止史上最全的微信小程序项目实例, 微信小程序实战学习

    wx-gesture-lock  微信小程序的手势密码 WXCustomSwitch 微信小程序自定义 Switch 组件模板 WeixinAppBdNovel 微信小程序demo:百度小说搜索 sh ...

  8. php小程序地图处理,微信小程序 地图map详解及简单实例

    微信小程序 地图map 微信小程序map 地图属性名类型默认值说明longitudeNumber中心经度 latitudeNumber中心纬度 scaleNumber1缩放级别 markersArra ...

  9. 【微信小程序系列】微信小程序超简单教程,基本语法,获取用户基本数据信息,实现对云数据库的增删改查及小程序外部api的引用示例(附源码)

    [微信小程序系列]微信小程序超简单教程 小程序项目结构 静态页面的构成 HTML:结构 css:样式 js:行为 小程序 页面全部存放在pages, 而且pages目录只能存放页面 页面包括4个文件, ...

最新文章

  1. 牛客网:为什么不能将实数作为 HashMap 的 key?
  2. integer是值传递还是引用传递_数据值Value传递-高位传递
  3. android源码framework下添加新资源的方法
  4. 一些基本算法的递归实现
  5. POJ 3687 Labeling Balls【拓扑排序】
  6. jQuery操作CSS
  7. 防止VLAN间的ARP***解决方案
  8. wex5部署教程到数据库
  9. php在指定html元素中输出,如何从PHP中的数组输出html svg元素?
  10. 解决Scrapy使用pipline保存到数据库后返回None
  11. Semaphore使用,占桌把戏
  12. 【Sort】QuickSort
  13. 28388D上电时从BOOT跳转到main过程分析
  14. c语言大一,C语言复习 大一.doc
  15. WIN10系统盘安装提示MBR分区问题解决步骤
  16. RAC-OCR,VIP,VOTEING DISK
  17. 怎样把多个TXT文件合成为一个TXT文件
  18. 计算机硬件系统中外设,计算机及外设 计算机硬件系统
  19. 2022-2028年全球与中国防水翘板开关行业产销需求与投资预测分析
  20. 企业如何搭建属于自己的协同办公管理系统?

热门文章

  1. mysql建立外键快捷方式_mysql建立外键
  2. 面试(2)——StringBuffer StringBuilder String /==与equals
  3. pythonpil安装教程_Python 3.6 -win64环境安装PIL模块的教程
  4. 计算机图书管理属于计算机应用中的,计算机在图书管理中应用探究.doc
  5. html等待图片全部加载,imgLoad等待图片资源加载完成后执行函数(图片预加载)...
  6. aix oracle监听配置_Oracle数据库03用户权限与数据库的连接
  7. vscode 崩溃_太真实了!程序员崩溃的40个瞬间
  8. matlab soble滤波,MATLAB 图像滤波去噪分析及其应用
  9. java和php哪个开发网站好,网站开发,Java和php两种开发语言,应该选哪一种,你知道吗?...
  10. wordpress安装jquery插件失败_Contact Form 7插件_WordPress表单插件安装使用教程