tips.参考网上资料的改进版
1.怎么使用.html
<!--无限制需要在js代码里设置数量,upload为上传地址,或者说图片服务器 --> <up-pic url="{{upload}}"bindupImgData="upImgData"class='up-pic' notli/> <!--或者:限制只能少于9 --> <up-pic url="{{upload}}"bindupImgData="upImgData"count="8"class='up-pic'/>
1.2.怎么使用.js
//上传图片返回 upImgData(e) { //console.log(e.detail) this.setData({ images: e.detail }) },
1.3.怎么使用.json
{ "usingComponents": { "up-pic": "./up-pic/index"} }
2.核心组件代码
/up-ipc/
./up-ipc/index.js
/** * <up-pic url="{{upload}}" count="3" autoup class='up-pic'></up-pic> * * url:上传图片地址 * count:上传总数量(默认上传1张图片) * autoup:是否自动上传(无需传参数,参考以上) * 2019-04-15 MIT */import { promisify } from '../../../../utils/promise'const wxUploadFile =promisify(wx.uploadFile) const network = require("../../../../utils/upload.js") Component({ data: { imgs: [], upload_picture_list: [], count: 1, url: '', notli: false}, properties: { url: { type: String, observer(newVal, oldVal) { this.data.url =newVal; } }, count: { type: Number, observer(newVal, oldVal) { this.data.count =newVal; } }, notli: { type: Boolean } }, methods: { chooseImage() { cImage(this, parseInt(this.data.count), this.data.url); }, uploadimage() { uImage(this, this.data.url); }, deleteImg(e) { dImage(e, this); }, previewImg(e) { pImage(e, this); } } }) //上传图片(this,api.imageup) const uImage = (_that, url) =>{ //console.log(_that.data.upload_picture_list) uploadFileServer(url, _that, _that.data.upload_picture_list) } const uploadFileServer = (url, that, upload_picture_list) =>{ const upload =promisify(network.upload) //上传 const promises = upload_picture_list.map(function(item) { //console.log(item) if (item.path_server !== '') return; returnupload({ url: url, path: item['path'], name: 'file', extra: {}, myfn (data) { item.path_server=data.result that.setData({ upload_picture_list: upload_picture_list }); let images = that.data.upload_picture_list.map(e =>e.path_server) that.setData({ images: images }); that.triggerEvent('upImgData', images); }, progress (res) { //console.log('上传进度', res.progress) item.upload_percent =res.progress that.setData({ upload_picture_list: upload_picture_list }); } }) }) } //删除图片 const dImage = (e, _that) =>{ _that.data.upload_picture_list.splice(e.currentTarget.dataset.index, 1); _that.data.imgs.splice(e.currentTarget.dataset.index, 1); _that.setData({ upload_picture_list: _that.data.upload_picture_list }); let images = _that.data.upload_picture_list.map(e =>e.path_server) _that.setData({ images: images }); _that.triggerEvent('upImgData', images); } //选择图片 const cImage = (_that, count, url) =>{ wx.chooseImage({ count: _that.data.notli ? count = 20: count, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function(res) { _that.data.imgs =_that.data.imgs.concat(res.tempFilePaths) for (let i inres.tempFiles) { res.tempFiles[i]['upload_percent'] = 0res.tempFiles[i]['path_server'] = ''_that.data.upload_picture_list.push(res.tempFiles[i]); _that.data.upload_picture_list.length > count ? _that.data.upload_picture_list = _that.data.upload_picture_list.slice(0, count) : console.log(); } !_that.data.notli && count == _that.data.upload_picture_list.length ?uImage(_that, url) : console.log(); _that.data.notli && count == 20 ?uImage(_that, url) : console.log(); _that.data.notli ? console.log(`%c 开启无限制上传图片模式(单次选择最多20张)`, `color:#f00;font-weight:bold;`) : console.log(`%c 开启限制上传图片模式,目标数量为:${count}`, `color:#f00;font-weight:bold;`); _that.data.upload_picture_list = _that.data.upload_picture_list.slice(0, count); _that.setData({ upload_picture_list: _that.data.upload_picture_list, }); //console.log(_that.data.upload_picture_list) } }) } //预览图片 const pImage = (e, _that) =>{ let percent =e.currentTarget.dataset.percent if (percent === '1') { wx.previewImage({ current: _that.data.images[e.currentTarget.dataset.index], urls: _that.data.images }) } else{ wx.previewImage({ current: _that.data.imgs[e.currentTarget.dataset.index], urls: _that.data.imgs }) } }
./up-ipc/index.json
{ "component": true}
./up-ipc/index.wxml
<view class='sunsin'> <view class="sunsin_picture_list"> <view wx:for="{{upload_picture_list}}"class="sunsin_picture_item"wx:key="{{index}}"> <image wx:if="{{item.upload_percent < 100}}"src="{{item.path}}"mode="aspectFill"></image> <image wx:if="{{item.upload_percent == 100}}"data-index="{{index}}"src="{{item.path_server}}"mode="aspectFill"bindtap="previewImg"data-percent="1"></image> <view class="sunsin_upload_progress"wx:if="{{item.upload_percent < 100}}"data-index="{{index}}"bindtap="previewImg"data-percent="0">{{item.upload_percent}}%</view> <text class='del' bindtap='deleteImg' data-src='{{image}}' style='display:{{isDel}}' data-index="{{index}}">×</text> </view> <view class='sunsin_picture_item' wx:if="{{upload_picture_list.length<count || notli}}"> <view class="sunsin-add-image"bindtap='chooseImage'> <text class='iconfont icon-tupianshangchuan'></text> </view> </view> </view> </view>
./up-ipc/index.wxss
@import "iconfont"; image {width:40rpx;height:40rpx;margin:0 4%; } .icon-tupianshangchuan {font-size:73rpx; } .sunsin_picture_list {width:100%;padding:20rpx;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:flex-start;flex-direction:row;justify-content:flex-start; } .sunsin_picture_list image {width:40rpx;height:40rpx;margin:0 4%; } .sunsin-add-image {width:150rpx;height:150rpx;color:#ddd;font-size:144rpx;line-height:62%;text-align:center;margin:2% 0 0 2%;background-color:#eee;cursor:pointer;border-radius:10rpx; } .sunsin_picture_item {margin:20rpx;margin-left:0;position:relative;width:160rpx;height:160rpx; } .sunsin_picture_item .del {position:absolute;top:0;right:-6rpx;color:#fff;border-radius:4rpx;width:40rpx;height:40rpx;line-height:40rpx;z-index:2;text-align:center;background-color:#e54d42; } .sunsin_upload_progress {font-size:24rpx;color:#fff;width:167rpx;height:160rpx;text-align:center;line-height:160rpx;position:absolute;top:0;left:0;opacity:0.7;border-radius:8rpx;background-color:#000; } .sunsin_picture_item image {width:160rpx;height:160rpx;border-radius:3px; } .sunsin-yes-upload {color:#fff;border-radius:0;background-color:#00a0e9; }
./up-ipc/iconfont.wxss
@font-face {font-family:"iconfont";src:url('iconfont.eot?t=1552565213642'); /*IE9 */src:url('iconfont.eot?t=1552565213642#iefix') format('embedded-opentype'), /*IE6-IE8 */url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAANIAAsAAAAAB0AAAAL6AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAqCQIIXATYCJAMICwYABCAFhG0HOhtHBhHVmz3IfibYjlEWYEvmdtInlWCZnjPBw2dX/arqwXWvwOwsL8yXn5lBjqcBAujAB8DmZugaFaFYkvO8n74jHRPS8MMn7p3+lvh8QDmOtWmsSV2A8daA9sYoobRAAvO4YeyCF3gbAtAJEEcMHT52KlY07EUCEGtXrViEtaBF60gXWBGYG3ZqiFxMWOUpeQfIiT4vvpKSFSQmhZ01cfmwpQz8UOVEqYO2g3MDAt5yZoDtAwXEAQ3E1EbreFQSiKPQ9YBGCI6VLuBDlc0WcA/7wwMBwoydageAH+Q+E8/jP2qRBEDj2QdXAtsnvRSYvBzt/bz2FJ92m1p4sC3DcwBFbU0dQvQryug45LG8oj6m/VpYYy9VD9Mzbk8/5FlSYmS0HSx1O92+wanxjJdWdjbcUTgUtwvToQ7DMaMNaajyc1uLMjxnTMswmiJXlBxqP+22dHpx4+z/oCz1YcxJ35OzZp3yDvEuDblmyAs4XltW5h3qfco2tr0lfVpba+cbf0vqRv+Etf3sSz2uWuyDvP5eckxa8IPaVP2gnlobNJBX0m6gvXS84Cjtawde0FPfrSz1Lj1+fPNmIWPi+/Yt80r1LgsP37ytZGJZTc0qKwMBsF1dUEF//jus3RfdusCx73+roQHwqHfp82iO7RoqCLDen03Af+YNbNAMga2TmsZrjEhWYrr/Mh0dsMFOFy+mKt1fyiywFngMEgv+UFgJI2m0OJgwSIMZKwOgE2vEfgNXm1EIrQ8Q4xiAwEkPJA6ch8LJXZJGew4THr7DjFMKOtOF64kGEZlBDCGUjAbUH4Ju1boGFnH6Hd2VJeUFEf2N1IMblnEuh29YkZZY0z9uZbZgqRXYwX2Yc4ODWkTNo2c+tmmyTU8adSuDMIRQMhqg/iDoVm3QmkXl/Xd0V5bUUVfnfCP1MDxYjOYBpJu0Dqp7lEf6x62YLbDUCtjBNMy5gaN5WkTNIz/Bd2wmp5kdKh23l5e/2wbobJXMGaVw2nUEWbv3XE77K9AMAwAA') format('woff2'), url('iconfont.woff?t=1552565213642') format('woff'), url('iconfont.ttf?t=1552565213642') format('truetype'), /*chrome, firefox, opera, Safari, Android, iOS 4.2+ */url('iconfont.svg?t=1552565213642#iconfont') format('svg'); /*iOS 4.1- */ } .iconfont {font-family:"iconfont" !important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale; } .icon-tupianshangchuan:before {content:"e69d"; }
3.补充api封装
upload.js
functionupload(options) { var url =options.url, path =options.path, name =options.name, //data = options.data, extra =options.extra, success =options.success, progress = options.progress, //progress 方法 fail =options.fail, myfn =options.myfn const uploadTask =wx.uploadFile({ url: url, filePath: path, name: name, formData: extra, success: function(res) { //console.log(res); var data =res.data try{ data =JSON.parse(res.data) //console.log(data) } catch(e) { console.log(data) throw(e) } if (res.statusCode == 200) { if(success) { //console.log(data) success(data) myfn(data) } } else{ if(fail) { fail(data) } } }, fail: function(res) { console.log(res) if(fail) { fail(res) } } }) uploadTask.onProgressUpdate((res) =>{ //console.log('上传进度', res.progress) //console.log('已经上传的数据长度', res.totalBytesSent) //console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend) if(progress)( progress(res) ) }) } module.exports ={ upload: upload }
promise.js
/** * 将wx的callback形式的API转换成支持Promise的形式 */module.exports ={ promisify: api =>{ return (options, ...params) =>{ return new Promise((resolve, reject) =>{ const extras ={ success: resolve, fail: reject } api({ ...options, ...extras }, ...params) }) } } }
4.demo