原创: 龙衣
前言
虽然不会后台开发, 但是也想自己做项目, 正好云开发出现了. 开发者可以使用云开发开发微信小程序, 小游戏, 无需搭建服务器, 即可使用云端能力.
社区作为一个交流的平台, 可以通过发布自己, 别人喜欢的文字, 图片的方式进行交流分享.
刚学完云开发, 正好可以用社区小程序项目练练手~
[社区小程序] 功能实现
首页[广场]
●显示用户发布的内容
●管理员发布的一些教程
消息[发布]
●发布图文
●水平图片的滑动显示
个人中心[我的]
●显示用户的登录信息
●用户的收藏列表
●发布历史
●邀请好友
●产品意见
一, 首页[广场]
显示用户发布的内容
管理员发布的一些教程
实现的效果
实现要点
1.WXML 不同类别数据的显示
通过 if-elif-else 实现, 在 wxml 文件中通过 <block></block > 渲染, 因为它仅仅是一个包装元素, 不会在页面中做任何渲染, 只接受控制属性. 也就是说可以通过属性来控制页面是否要渲染这部分的内容, 可以减少页面渲染时间.
2. 云开发数据的获取
先开通云开发功能 , 参考官方文档, 然后在创建项目的时候勾选上 使用云开发模板 (看个人吧, 我直接使用后点击项目中的 login) 就可以获取到用户的 oppenid, 之后就可以使用云数据库了.
云开发登录:
云数据的获取:
- /**
- * 生命周期函数 -- 监听页面加载
- */
- onLoad: function(options) {
- console.log('onload');
- this.getData(this.data.page);
- },
- /**
- * 获取列表数据
- *
- */
- getData: function(page) {
- var that = this;
- console.log("page--->" + page);
- const db = wx.cloud.database();
- // 获取总数
- db.collection('topic').count({
- success: function(res) {
- that.data.totalCount = res.total;
- }
- })
- // 获取前十条
- try {
- db.collection('topic')
- .where({
- _openid: 'oSly***********vU1KwZE', // 填入当前用户 openid
- })
- .limit(that.data.pageSize) // 限制返回数量为 10 条
- .orderBy('date', 'desc')
- .get({
- success: function(res) {
- // res.data 是包含以上定义的两条记录的数组
- // console.log(res.data)
- that.data.topics = res.data;
- that.setData({
- topics: that.data.topics,
- })
- wx.hideNavigationBarLoading();// 隐藏加载
- wx.stopPullDownRefresh();
- },
- fail: function(event) {
- wx.hideNavigationBarLoading();// 隐藏加载
- wx.stopPullDownRefresh();
- }
- })
- } catch (e) {
- wx.hideNavigationBarLoading();// 隐藏加载
- wx.stopPullDownRefresh();
- console.error(e);
- }
- },
云数据的添加:
- /**
- * 保存到发布集合中
- */
- saveDataToServer: function(event) {
- var that = this;
- const db = wx.cloud.database();
- const topic = db.collection('topic')
- db.collection('topic').add({
- // data 字段表示需新增的 JSON 数据
- data: {
- content: that.data.content,
- date: new Date(),
- images: that.data.images,
- user: that.data.user,
- isLike: that.data.isLike,
- },
- success: function(res) {
- // res 是一个对象, 其中有 _id 字段标记刚创建的记录的 id
- // 清空, 然后重定向到首页
- console.log("success---->" + res)
- // 保存到发布历史
- that.saveToHistoryServer();
- // 清空数据
- that.data.content = "";
- that.data.images = [];
- that.setData({
- textContent: '',
- images: [],
- })
- that.showTipAndSwitchTab();
- },
- complete: function(res) {
- console.log("complete---->" + res)
- }
- })
- },
3. 数据列表的分页
主要就是定义一个临时数组存放加载上来的数据, 然后通过传递给对象, 最后传递到布局中去.
- /**
- * 页面上拉触底事件的处理函数
- */
- onReachBottom: function() {
- var that = this;
- var temp = [];
- // 获取后面十条
- if(this.data.topics.length <this.data.totalCount){
- try {
- const db = wx.cloud.database();
- db.collection('topic')
- .skip(5)
- .limit(that.data.pageSize) // 限制返回数量为 5 条
- .orderBy('date', 'desc') // 排序
- .get({
- success: function (res) {
- // res.data 是包含以上定义的两条记录的数组
- if (res.data.length> 0) {
- for(var i=0; i <res.data.length; i++){
- var tempTopic = res.data[i];
- console.log(tempTopic);
- temp.push(tempTopic);
- }
- var totalTopic = {};
- totalTopic = that.data.topics.concat(temp);
- console.log(totalTopic);
- that.setData({
- topics: totalTopic,
- })
- } else {
- wx.showToast({
- title: '没有更多数据了',
- })
- }
- },
- fail: function (event) {
- console.log("======" + event);
- }
- })
- } catch (e) {
- console.error(e);
- }
- }else{
- wx.showToast({
- title: '没有更多数据了',
- })
- }
- },
二, 消息[发布]
发布图文
水平图片的滑动显示(效果不是很好, 可以改为九宫格实现)
发布页面效果如下:
分析如何实现
导航栏的实现很简单就不说了, 可参考我之前的文章
重点是中间的 2 是内容区域
区域三是功能操作区
内容区域的实现
第一个是文本区域
第二个是水平的图片展示区域
在图片的右上角有关闭按钮, 这里使用的是 icon 组件.
主要的实现代码如下:
- <view class="content">
- <form bindsubmit="formSubmit">
- <view class="text-content">
- <view class='text-area'>
- <textarea name="input-content" type="text" placeholder="说点什么吧~" placeholder-class="holder" value="{{textContent}}" bindblur='getTextAreaContent'></textarea>
- </view>
- </view>
- <scroll-view class="image-group" scroll-x="true">
- <block wx:for='{{images}}' wx:for-index='idx'>
- <view>
- <image src='{{images[idx]}}' mode='aspectFill' bindtap="previewImg"></image>
- <icon type='clear' bindtap='removeImg' data-index="{{idx}}"></icon>
- </view>
- </block>
- </scroll-view>
- <view class='btn-func'>
- <button class="btn-img" bindtap='chooseImage'>选择图片</button>
- <button class="btn" formType='submit' open-type="getUserInfo">发布圈圈</button>
- <!-- <image hidden=''></image> -->
- </view>
- </form>
- </view>
布局样式如下:
.content { height: 100%; width: 100%; } textarea { width: 700rpx; padding: 25rpx 0; } .text-content { background-color: #f3efef; padding: 0 25rpx; } .image-group { display: flex; white-space: nowrap; margin-top: 30px; } .image-group view{ display: inline-block; flex-direction: row; width: 375rpx; height: 375rpx; margin-right: 20rpx; margin-left: 20rpx; background-color: #cfcccc; } .image-group view image{ width: 100%; height: 100%; align-items: center; } .image-group view icon{ display: inline-block; vertical-align: top; position: absolute } .btn-func { display: flex; flex-direction: column; width: 100%; position: absolute; bottom: 0; margin: 0 auto; align-items: center; } .btn-img { width: 220px; height: 45px; line-height: 45px; margin-top: 20px; margin-bottom: 20px; background-color: rgb(113, 98, 250); color: #fff; border-radius: 50px; } .btn { width: 220px; height: 45px; line-height: 45px; background-color: #d50310; color: #fff; border-radius: 50px; margin-bottom: 20px; }
页面布局之后就该从 JS 中去处理数据了, 在 JS 中主要实现的功能有:
文本内容的获取
图片的选择
图片的阅览
图片的删除
将结果发布到云数据库中
1. 文本内容的获取
/** * 获取填写的内容 */ getTextAreaContent: function(event) { this.data.content = event.detail.value; },
2. 图片的选择
/** * 选择图片 */ chooseImage: function(event) { var that = this; wx.chooseImage({ count: 6, success: function(res) { // tempFilePath 可以作为 img 标签的 src 属性显示图片 const tempFilePaths = res.tempFilePaths for (var i in tempFilePaths) { that.data.images = that.data.images.concat(tempFilePaths[i]) } // 设置图片 that.setData({ images: that.data.images, }) }, }) },
3. 图片的预览
// 预览图片 previewImg: function(e) { // 获取当前图片的下标 var index = e.currentTarget.dataset.index; wx.previewImage({ // 当前显示图片 current: this.data.images[index], // 所有图片 urls: this.data.images }) },
4. 图片的删除
/** * 删除图片 */ removeImg: function(event) { var position = event.currentTarget.dataset.index; this.data.images.splice(position, 1); // 渲染图片 this.setData({ images: this.data.images, }) },
5. 发布内容到数据库中
数据发布到数据中, 需要先开启云开发, 然后在数据库中创建集合也就是表之后就是调用数据库的增删改查 API 即可.
/** * 添加到发布集合中 */ saveToHistoryServer: function(event) { var that = this; const db = wx.cloud.database(); db.collection('history').add({ // data 字段表示需新增的 JSON 数据 data: { content: that.data.content, date: new Date(), images: that.data.images, user: that.data.user, isLike: that.data.isLike, }, success: function(res) { // res 是一个对象, 其中有 _id 字段标记刚创建的记录的 id console.log(res) }, fail: console.error }) },
三, 个人中心[我的]
[显示用户的登录信息] 主要就是调用小程序接口, 获取用户的微信公开信息进行展示
[用户的收藏列表] 获取数据库中的收藏列表进行展示
[发布历史] 在发布页面, 当发布成功将数据存到发布历史表中, 需要的时候获取该表的数据进行展示
[邀请好友] 调用小程序的分享接口, 直接分享给微信群, 或者个人
[产品意见] 一个类似于发布页的页面, 实现思路和发布页实现是一样的.
实现的效果
实现分析
1. 要实现的效果
在用户进入个人中心, 直接弹出获取用户信息弹窗
显示圆形的用户头像
2. 授权弹窗
官方获取用户信息文档调整
为优化用户体验, 使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持. 从 2018 年 4 月 30 日开始, 小程序与小游戏的体验版, 开发版调用 wx.getUserInfo 接口, 将无法弹出授权询问框, 默认调用失败. 正式版暂不受影响.
也就是以前的 wx.getUserInfo 不直接弹出授权窗口了, 而且在新版中调用会直接返回 fail, 现在的做法呢就是通过点击一个 button 去实现用户授权功能.
文档中说明了有两种方式能够获取用户信息.
一个是利用 <open-data > 获取公开的用户信息:
<open-data type="userNickName" lang="zh_CN"> </open-data> <open-data type="userAvatarUrl"> </open-data> <open-data type="userGender" lang="zh_CN"> </open-data>
另一个是利用 button 组件将 open-type 指定为 getUserInfo 类型:
<!-- 需要使用 button 来授权登录 --> <button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button> <view wx:else > 请升级微信版本</view> Page({ data: { canIUse: wx.canIUse('button.open-type.getUserInfo') }, onLoad: function() { // 查看是否授权 wx.getSetting({ success (res){ if (res.authSetting['scope.userInfo']) { // 已经授权, 可以直接调用 getUserInfo 获取头像昵称 wx.getUserInfo({ success: function(res) { console.log(res.userInfo) } }) } } }) }, bindGetUserInfo (e) { // 获取到用户信息 console.log(e.detail.userInfo) } })
3.<open-data > 中实现圆形头像
<view class='amountBg'> <view class='img'> <open-data type="userAvatarUrl"></open-data> </view> <view class='account'> <view class='nick-name'> <open-data type="userNickName" lang="zh_CN"></open-data> </view> <view class='address'> <open-data type="userCountry" lang="zh_CN"></open-data>. <open-data type="userProvince" lang="zh_CN"></open-data>. <open-data type="userCity" lang="zh_CN"></open-data> </view> </view> </view>
CSS 样式如下:
.amountBg { display: flex; flex-direction: row; height: 100px; background-color: #5495e6; align-items: center; } .img { overflow: hidden; display: block; margin-left: 20px; width: 49px; height: 49px; border-radius: 50%; } .account { width: 70%; color: #fff; margin-left: 10px; align-items: center; } .nick-name{ font-family: 'Mcrosoft Yahei'; font-size: 16px; } .address{ font-size: 13px; } .nav { width: 15px; color: #fff; }
可能存在的一些问题
其他用户发布的内容, 有时候显示不出来? 将数据库的权限设置为全部人可见.
发布内容之后返回首页没有自动刷新? 在广场首页 onShow 的时候获取数据库的数据进行展示.
clone 源码后运行不起来? 需要在自己的云数据库中创建对应的表.
来源: https://www.qcloud.com/developer/article/1408405