目录
- 目标及基础环境
- 背景
- 实现原理
- 左右滑动
- 缩放
- 图片菜单
- 开发实现
- 自定义组件
- wxml组件结构
- wxss 样式控制
- js定义属性及回调
- json声明为组件
- 使用
- 添加组件声明及地址
- 声明为全局组件(也可声明为局部)
- 声明为全局组件(也可以声明为全局组件)
- 使用组件
- 效果展示
- 附:
目标及基础环境
背景
微信自带的 wx.previewImage()在图片预览时须传递所有图片的URL,当图片无法直接访问(如需携带cookies),须一次性下载所有图片,转换成本地地址后放入url参数中,此过程用户需要等待时间又比较长时,导致用户体验较差;
基于如上问题,自定义小程序组件实现如下功能:
- 模拟图片预览功能;
- 支持菜单、左右滑动预览上、下一张;
- 预览图与原图的分离显示,即可在需要时加载原图
实现原理
左右滑动
使用swiper、swiper-item组件实现左右滑动
缩放
使用movable-area、movable-view实现图片缩放
图片菜单
通过设置image组件的show-menu-by-longpress="true"实现菜单功能
开发实现
自定义组件
wxml组件结构
基于实现原理源代码如下:
<!--components/imgview/imgview.wxml-->
<text class="self-closeImgview" bindtap="closeImgview">X</text>
<swiper current="{{current}}" circular="true" style="width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.9);position: absolute;top: 0;">
<block wx:for="{{imagelist}}" wx:key="id">
<swiper-item style="width: 100%;height: 100%; ">
<movable-area scale-area="true" style="margin-top: 5%;height: 90%;width: 100%;">
<movable-view direction="all" scale="true" direction="true" style="height: 100%;width: 100%;">
<image src="{{item.thumbUrl}}" mode="aspectFit" show-menu-by-longpress="{{showmenu}}" style="min-height: 100%;min-width: 100%;"></image>
</movable-view>
</movable-area>
<view class="self-viewimg-control">
<text>{{item.desc}}</text>
<text class="self-viewimg-orginbtn" data-originurl="{{item.imgUrl}}" bindtap="vieworigin">查看原图</text>
</view>
</swiper-item>
</block>
</swiper>
wxss 样式控制
.self-viewimg-control {
color: white;
position: absolute;
bottom: 30px;
left: 2%;
font-size: 0.85rem;
}
.self-viewimg-control text {
display: inline-table
}
.self-viewimg-orginbtn {
border-radius: 6px;
padding: 1px;
border: 1px solid white;
}
.self-closeImgview {
position: absolute;
right: 2%;
top: 2%;
border: 1px solid white;
color: white;
z-index: 9999;
border-radius: 10px;
display: block;
width: 20px;
height: 20px;
text-align: center;
}
js定义属性及回调
注意组件中的属性定义
- 组件的属性列表
- current: 当前查看图片的索引号
- showmenu: 是否展示图片菜单
- imagelist: 图片数组对象
-
- thumbUrl:缩略图地址,组件将展示此图地址,可左右滑动切换
-
- imgUrl: 原图地址,用户点击“查看原图”加载原图显示
-
- desc: 图片备注信息
- changeStatus: 回调函数,用户通知父组件数据变化
Component({
/**
* 组件的属性列表
* current: 当前查看图片的索引号
* showmenu: 是否展示图片菜单
* imagelist: 图片数组对象
* thumbUrl:缩略图地址,组件将展示此图地址,可左右滑动切换
* imgUrl: 原图地址,用户点击“查看原图”加载原图显示
* desc: 图片备注信息
* changeStatus: 回调函数,用户通知父组件数据变化
*/
properties: {
current: {
defaultval: 1,
type: Number
},
showmenu:{
defaultval: false,
type: Boolean
},
preview: {
defaultval: true,
type: Boolean
},
imagelist:{
type: []
},
changeStatus:{
type: Function
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
vieworigin: function(data) {
console.log(data.currentTarget.dataset.originurl,"+++++")
/*
wx.previewImage({
urls: [data.currentTarget.dataset.originurl],
})
*/
const url = data.currentTarget.dataset.originurl;
if(url) {
wx.showLoading({
"title":"原图下载中"
})
/* 此过程须根据实际需要实现下载原图逻辑
commonUtils.downloadFile(url,function(tmpurl) {
wx.hideLoading()
//图片预览
wx.previewImage({
urls: [tmpurl] // 需要预览的图片http链接列表
})
})
*/
/**下载原图后使用wx.previewImage()实现原生方法加载图片预览*/
wx.previewImage({
urls: [url ] // 需要预览的图片http链接列表
})
}else {
commonUtils.errorToast("数据错误!")
}
},
closeImgview: function(data) {
// 回调组件所在父组件方法传值
this.triggerEvent("changeStatus",false)
}
}
})
json声明为组件
{
"component": true
}
使用
app.json中添加如下内容
添加组件声明及地址
“pages”: [] 添加组件地址,如:
"pages": [
"components/imgview/imgview"
]
声明为全局组件(也可声明为局部)
"usingComponents": {
"imgview": "/components/imgview/imgview"
},
声明为全局组件(也可以声明为全局组件)
在对应页面的json文件中添加如下内容
{
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
使用组件
在需要的页面添加自定义组件,像原生组件一样使用
<imgview class="self-imgview-desc" imagelist="{{imagelist}}" current="{{currindex}}" showmenu="true" bind:changeStatus="changeStatus" wx:if="{{preview}}"></imgview>
效果展示
没有备注信息的效果
带备注信息的效果
图片带菜单的效果
缩放效果(真机效果)
查看原图效果
附:
微信开发文档之自定义组件