随着小程序云开发愈来愈成熟,如今用云开发能够作的事情也愈来愈多,今天就来带你们实现小程序朋友圈功能。正则表达式
下面是咱们真正存到数据库里的数据。
而后咱们在朋友圈页只须要请求数据库里的数据,而后展现到页面就以下图所示
因此咱们接下来就来实现发布和展现的功能数据库
这里就很少说了,若是你还不知道如何建立小程序项目能够去翻看下我以前的文章,也能够看下我录制的《10小时零基础入门小程序开发》编程
咱们发布页布局比较简单,一个文字输入框,一个图片展现区域,一个发布按钮。
先把发布页布局wxml贴出来小程序
<textarea class="desc" placeholder="请输入内容" bindinput="getInput" /> <view class="iamgeRootAll"> <view class="imgRoot" wx:for="{{imgList}}" wx:key="{{index}}" bindtap="ViewImage" data-url="{{imgList[index]}}"> <view wx:if="{{imgList.length==(index+1)&& imgList.length<8}}" class="imgItem" bindtap="ChooseImage"> <image class="photo" src="../../images/photo.png"></image> </view> <view wx:else class="imgItem" data-index="{{index}}"> <image class="img" src='{{item}}' mode='aspectFill'></image> <image class="closeImg" bindtap="DeleteImg" src="../../images/close.png" data-index="{{index}}"></image> </view> </view> <!-- 一开始用来占位 --> <view wx:if="{{imgList.length==0}}" class="imgItem" bindtap="ChooseImage"> <image class="photo" src="../../images/photo.png"></image> </view> </view> <button type="primary" bindtap="publish">发布朋友圈</button>
这里惟一的难点,就是下面的图片分布,由于咱们每次用户选择的图片个数不固定,这就要去分状况考虑了。
wx:if="{{imgList.length==(index+1)&& imgList.length<8}}"这段代码是用来控制咱们发布的那个➕ 号的显示与隐藏的。api
这个➕号有下面三种状况须要考虑数组
图片选择很简单,就用官方的api便可。实现代码以下promise
//选择图片 ChooseImage() { wx.chooseImage({ count: 8 - this.data.imgList.length, //默认9,咱们这里最多选择8张 sizeType: ['original', 'compressed'], //能够指定是原图仍是压缩图,默认两者都有 sourceType: ['album'], //从相册选择 success: (res) => { console.log("选择图片成功", res) if (this.data.imgList.length != 0) { this.setData({ imgList: this.data.imgList.concat(res.tempFilePaths) }) } else { this.setData({ imgList: res.tempFilePaths }) } } }); },
这里单独说明下 8 - this.data.imgList.length。由于我这里规定最多只能上传8张图片。因此用了count8 ,至于后面为何要减去this.data.imgList.length。主要是咱们用户不必定一次选择8张图片,有可能第一次选择2张,第二次选择2张。。。
因此咱们作选择时,每次传入的数量确定不同的。而这个imgList.length就是用户已经选择的图片个数。用8减去已选择的个数,就是下次最多能选择的了。微信
上面代码在选择成功后,会生成一个临时的图片连接。以下图所示,这个连接既能够用来展现咱们已经选择的图片,后面的图片上传也要用到。网络
咱们每张图片的右上角有个删除按钮,点击删除按钮能够实现图片的删除。
这里比较简单,把代码贴给你们app
//删除图片 DeleteImg(e) { wx.showModal({ title: '要删除这张照片吗?', content: '', cancelText: '取消', confirmText: '肯定', success: res => { if (res.confirm) { this.data.imgList.splice(e.currentTarget.dataset.index, 1); this.setData({ imgList: this.data.imgList }) } } }) },
2,因为咱们发布的时候要保证全部的图片都要上传成功,因此这里咱们这么处理。
const promiseArr = [] //只能一张张上传 遍历临时的图片数组 for (let i = 0; i < this.data.imgList.length; i++) { let filePath = this.data.imgList[i] let suffix = /\.[^\.]+$/.exec(filePath)[0]; // 正则表达式,获取文件扩展名 //在每次上传的时候,就往promiseArr里存一个promise,只有当全部的都返回结果时,才能够继续往下执行 promiseArr.push(new Promise((reslove, reject) => { wx.cloud.uploadFile({ cloudPath: new Date().getTime() + suffix, filePath: filePath, // 文件路径 }).then(res => { // get resource ID console.log("上传结果", res.fileID) this.setData({ fileIDs: this.data.fileIDs.concat(res.fileID) }) reslove() }).catch(error => { console.log("上传失败", error) }) })) } //保证全部图片都上传成功 Promise.all(promiseArr).then(res => { //图片上传成功了,才会执行到这。。。 })
咱们这里用Promise来确保全部的图片都上传成功了,才执行后面的操做。
/** * 编程小石头 * wehchat:2501902696 */ let app = getApp(); Page({ data: { imgList: [], fileIDs: [], desc: '' }, //获取输入内容 getInput(event) { console.log("输入的内容", event.detail.value) this.setData({ desc: event.detail.value }) }, //选择图片 ChooseImage() { wx.chooseImage({ count: 8 - this.data.imgList.length, //默认9,咱们这里最多选择8张 sizeType: ['original', 'compressed'], //能够指定是原图仍是压缩图,默认两者都有 sourceType: ['album'], //从相册选择 success: (res) => { console.log("选择图片成功", res) if (this.data.imgList.length != 0) { this.setData({ imgList: this.data.imgList.concat(res.tempFilePaths) }) } else { this.setData({ imgList: res.tempFilePaths }) } } }); }, //删除图片 DeleteImg(e) { wx.showModal({ title: '要删除这张照片吗?', content: '', cancelText: '取消', confirmText: '肯定', success: res => { if (res.confirm) { this.data.imgList.splice(e.currentTarget.dataset.index, 1); this.setData({ imgList: this.data.imgList }) } } }) }, //上传数据 publish() { let desc = this.data.desc let imgList = this.data.imgList if (!desc || desc.length < 6) { wx.showToast({ icon: "none", title: '内容大于6个字' }) return } if (!imgList || imgList.length < 1) { wx.showToast({ icon: "none", title: '请选择图片' }) return } wx.showLoading({ title: '发布中...', }) const promiseArr = [] //只能一张张上传 遍历临时的图片数组 for (let i = 0; i < this.data.imgList.length; i++) { let filePath = this.data.imgList[i] let suffix = /\.[^\.]+$/.exec(filePath)[0]; // 正则表达式,获取文件扩展名 //在每次上传的时候,就往promiseArr里存一个promise,只有当全部的都返回结果时,才能够继续往下执行 promiseArr.push(new Promise((reslove, reject) => { wx.cloud.uploadFile({ cloudPath: new Date().getTime() + suffix, filePath: filePath, // 文件路径 }).then(res => { // get resource ID console.log("上传结果", res.fileID) this.setData({ fileIDs: this.data.fileIDs.concat(res.fileID) }) reslove() }).catch(error => { console.log("上传失败", error) }) })) } //保证全部图片都上传成功 Promise.all(promiseArr).then(res => { wx.cloud.database().collection('timeline').add({ data: { fileIDs: this.data.fileIDs, date: app.getNowFormatDate(), createTime: db.serverDate(), desc: this.data.desc, images: this.data.imgList }, success: res => { wx.hideLoading() wx.showToast({ title: '发布成功', }) console.log('发布成功', res) wx.navigateTo({ url: '../pengyouquan/pengyouquan', }) }, fail: err => { wx.hideLoading() wx.showToast({ icon: 'none', title: '网络不给力....' }) console.error('发布失败', err) } }) }) }, })
到这里咱们发布的功能就实现了,发布功能就以下面这个流程图所示。
咱们最终的目的是要把文字和图片连接存到云数据库。把图片文件存到云存储。这就是云开发的方便之处,不用咱们编写后台代码,就能够轻松实现后台功能。
这个页面主要作的就是
这里读取数据挺简单,就是从云数据库读数据,这里咱们作了一个排序,就是最新发布的数据在最上面。代码以下
wx.cloud.database().collection('timeline') .orderBy('createTime', 'desc') //按发布视频排序 .get({ success(res) { console.log("请求成功", res) that.setData({ dataList: res.data }) }, fail(res) { console.log("请求失败", res) } })
云数据库的读取也比较简单,有不会的同窗,或者没有据说太小程序云开发的同窗,能够去翻看下我以前发的文章,也能够看下我录的《10小时零基础入门小程序云开发》
这里也比较简单,直接把布局代码贴给你们。dataList就是咱们第一步请求到的数据。
<block wx:for="{{dataList}}" wx:key="index"> <view class="itemRoot"> <view> <text class="desc">{{item.desc}}</text> </view> <view class="imgRoot"> <block class="imgList" wx:for="{{item.fileIDs}}" wx:for-item="itemImg" wx:key="index"> <image class="img" src='{{itemImg}}' mode='aspectFill' data-img='{{[itemImg,item.fileIDs]}}' bindtap="previewImg"></image> </block> </view> </view> </block>
功能实现很简单就下面几行代码,可是咱们从wxml获取组件上的数据时比较麻烦。
// 预览图片 previewImg: function(e) { let imgData = e.currentTarget.dataset.img; console.log("eeee", imgData[0]) console.log("图片s", imgData[1]) wx.previewImage({ //当前显示图片 current: imgData[0], //全部图片 urls: imgData[1] }) },
咱们点击组件时,能够经过data- 传递数据,可是一个点击若是像传多条数据呢。这时候能够用 data-xxx='{{[xxx,xxx]}}' 来传递数据了。以下代码
<block wx:for="{{item.fileIDs}}" wx:key="item2" wx:for-item="item2"> <image src='{{item2}}' data-img='{{[item2,item.fileIDs]}}' mode='aspectFill' bindtap="previewImg"></image> </block> //咱们再js里能够接收两个数据 previewImg: function(e) { let imgData = e.currentTarget.dataset.img; console.log("item2", imgData[0]) console.log("item.fileIDs", imgData[1]) //大图预览 wx.previewImage({ //当前显示图片 current: imgData[0], //全部图片 urls: imgData[1] }) },
上面代码就能够实现,一次点击,经过data- 传递多个数据到js里。
朋友圈展现的比较简陋,后期再抽时间作美化吧。
源码我已经上传到网盘,须要的同窗能够加我微信2501902696获取
后面我也会录制一套视频来专门讲解。敬请关注。