微信小程序之如何使用自定義組件封裝原生image組件
小程序原生組件image組件沒(méi)有常用的功能,所以以下小編為大家介紹微信小程序之如何使用自定義組件封裝原生image組件 ?

一常規(guī)操作
在小程序沒(méi)還沒(méi)推出自定義組件功能時(shí),只能通過(guò)改變 Page 中的 data 來(lái)展示兜底的占位圖,所以當(dāng)時(shí)的處理方式十分蛋疼...
1.1.相同默認(rèn)圖
由于需要知道這個(gè)圖片的數(shù)據(jù)路徑,所以不得不在每個(gè) image 上加上類(lèi)似 data-img-path 的東西。
<view
wx:for="{{ obj.arr }}"
wx:key="imgSrc"
wx:for-item="item"
wx:for-index="itemIdx"
>
<image
src="{{ item.imgSrc }}"
binderror="onImageError"
data-img-path="obj.arr[{{ itemIdx }}].imgSrc"
/>
</view>
復(fù)制代碼
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,
})
},
})
復(fù)制代碼
1.2.不同默認(rèn)圖
如果默認(rèn)圖片不同呢?例如球員、球隊(duì)和 feed 的默認(rèn)圖片一般都是不同的。
那么一般只好再增加一個(gè)屬性例如 data-img-type 來(lái)標(biāo)識(shí)默認(rèn)圖的類(lèi)型。
<!-- 球隊(duì)圖 -->
<image
...
data-img-type="team"
/>
<!-- 球員圖 -->
<image
...
data-img-type="player"
/>
復(fù)制代碼
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],
})
},
})
復(fù)制代碼
1.3.圖片在模板中
頁(yè)面層級(jí)淺倒還好,如果跨模板了,那么模板就可能要用一個(gè)類(lèi)似于 pathPrefix 的屬性來(lái)傳遞模板數(shù)據(jù)的路徑前綴。
<!--
球員排行模板
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>
復(fù)制代碼
最后在失敗回調(diào)里調(diào)用 setData({ [path]: DEFAULT_IMG }) 重新設(shè)置圖片地址。
二自定義組件
2.1.原生自定義組件
原生寫(xiě)法一般要寫(xiě)4個(gè)文件:.json/.wxml/.js/.wxss
- TuaImage.json
{
"component": true
}
復(fù)制代碼
- TuaImage.wxml
<!-- 加載中的圖片 -->
<image
hidden="{{ !isLoading }}"
src="{{ errSrc }}"
style="width: {{ width }}; height: {{ height }}; {{ styleStr }}"
mode="{{ imgMode }}"
/>
<!-- 實(shí)際加載的圖片 -->
<image
hidden="{{ isLoading }}"
src="{{ imgSrc || src }}"
mode="{{ imgMode }}"
style="width: {{ width }}; height: {{ height }}; {{ styleStr }}"
bindload="_onImageLoad"
binderror="_onImageError"
lazy-load="{{ true }}"
/>
復(fù)制代碼
- TuaImage.js
const DEFAULT_IMG = '/assets/your_default_img'
Component({
properties: {
// 圖片地址
src: String,
// 圖片加載中,以及加載失敗后的默認(rèn)地址
errSrc: {
type: String,
// 默認(rèn)是球隊(duì)圖標(biāo)
value: DEFAULT_IMG,
},
width: {
type: String,
value: '48rpx',
},
height: {
type: String,
value: '48rpx',
},
// 樣式字符串
styleStr: {
type: String,
value: '',
},
// 圖片裁剪、縮放的模式(詳見(jiàn)文檔)
imgMode: {
type: String,
value: 'scaleToFill',
},
},
data: {
imgSrc: '',
isLoading: true,
},
methods: {
// 加載圖片出錯(cuò)
_onImageError (e) {
this.setData({
imgSrc: this.data.errSrc,
})
this.triggerEvent('onImageError', e)
},
// 加載圖片完畢
_onImageLoad (e) {
this.setData({ isLoading: false })
this.triggerEvent('onImageLoad', e)
},
},
})
復(fù)制代碼
布吉島大家使用原生寫(xiě)法時(shí)有木有一些感覺(jué)不方便的地方:
- 4個(gè)文件:.json/.wxml/.js/.wxss,這樣老需要切來(lái)切去的降低效率
- properties 是什么鬼?大家(React/Vue)一般不都用 props 么?
- style="width: {{ width }}; height: {{ height }}; {{ styleStr }}" 樣式字符串怎么辣么長(zhǎng)...
2.2.TuaImage.vue
所以以下是一個(gè)使用單文件組件封裝原生 image 組件的例子。
- 使用單文件組件將配置、模板、腳本、樣式寫(xiě)在一個(gè)文件中,方便維護(hù)。
- 使用計(jì)算屬性 computed 將樣式字符串寫(xiě)在 js 中。
- 使用 this.imgSrc = this.errSrc 而不是 this.setData 來(lái)改變 data。
<config>
{
"component": true
}
</config>
<template lang="wxml">
<!-- 加載中的圖片 -->
<image
hidden="{{ !isLoading }}"
src="{{ errSrc }}"
style="{{ imgStyleStr }}"
mode="{{ imgMode }}"
/>
<!-- 實(shí)際加載的圖片 -->
<image
hidden="{{ isLoading }}"
src="{{ imgSrc || src }}"
mode="{{ imgMode }}"
style="{{ imgStyleStr }}"
bindload="_onImageLoad"
binderror="_onImageError"
lazy-load="{{ true }}"
/>
</template>
<script>
/**
* 圖片組件,能夠傳遞備用圖片以防圖片失效
* https://developers.weixin.qq.com/miniprogram/dev/component/image.html
*/
// 也可以設(shè)置為網(wǎng)絡(luò)圖片如: https://foo/bar.png
const DEFAULT_IMG = '/assets/your_default_img'
export default {
props: {
// 圖片地址
src: String,
// 圖片加載中,以及加載失敗后的默認(rèn)地址
errSrc: {
type: String,
// 默認(rèn)是球隊(duì)圖標(biāo)
default: DEFAULT_IMG,
},
width: {
type: String,
default: '48rpx',
},
height: {
type: String,
default: '48rpx',
},
// 樣式字符串
styleStr: {
type: String,
default: '',
},
// 圖片裁剪、縮放的模式(詳見(jiàn)文檔)
imgMode: {
type: String,
default: 'scaleToFill',
},
},
data () {
return {
imgSrc: '',
isLoading: true,
}
},
computed: {
// 樣式字符串
imgStyleStr () {
return `width: ${this.width}; height: ${this.height}; ${this.styleStr}`
},
},
methods: {
// 加載圖片出錯(cuò)
_onImageError (e) {
this.imgSrc = this.errSrc
this.$emit('onImageError', e)
},
// 加載圖片完畢
_onImageLoad (e) {
this.isLoading = false
this.$emit('onImageLoad', e)
},
},
}
</script>
<style lang="scss">
</style>
復(fù)制代碼
HiShop小程序工具提供多類(lèi)型商城/門(mén)店小程序制作,可視化編輯 1秒生成5步上線(xiàn)。通過(guò)拖拽、拼接模塊布局小程序商城頁(yè)面,所看即所得,只需要美工就能做出精美商城。更多小程序商店請(qǐng)查看:小程序商店

立即掃碼關(guān)注

多門(mén)店/直營(yíng)/加盟連鎖管理系統(tǒng)