在学习成长的过程当中,经常会遇到一些本身从未接触的事物,这就比如是打怪升级,每次打倒一只怪,都会得到经验,让本身进步强大。特别是咱们这些作技术的,逆水行舟不进则退。下面分享下小程序开发中的打怪升级经历~html
先来看下实际效果图,小程序开发中有时会要作一些的功能复杂的组件,好比评论回复和发帖功能等,此次主要讲的是关于评论模块的一些思路和实战中的经验,但愿能抛砖引玉,给你们一些启发,一同成长~前端
>>(最下面有实战demo的地址,能够直接浏览器打开添加至IDE工具中) <<node
根据这个demo.gif,本人作了一个简单的流程图,帮助你们理解。下面罗列一些开发中须要“ 打的怪”:
├─components ---小程序自定义组件 │ ├─plugins --- (重点)可独立运行的大型模块,能够打包成plugins │ │ ├─comment ---评论模块 │ │ │ │ index.js │ │ │ │ index.json │ │ │ │ index.wxml │ │ │ │ index.wxss │ │ │ │ services.js ---(重点)用来处理和清洗数据的service.js,配套模板和插件 │ └─submit ---评论模块子模块:提交评论 index.js index.json index.wxml index.wxss
为何要单独作个评论页面页面(submit)?
由于若是是当前页面最下面input输入的形式,会出现一些兼容问题,好比:react
注:目录结构,仅供参考。json
//node:API接口返回 { "data": { "commentTotal": 40, "comments": [ { "contentText": "喜欢就关注我", //评论内容 "createTime": 1560158823647, //评论时间 "displayName": "智酷方程式", //用户名 "headPortrait": "https://blz.nosdn.127.net/1/weixin/zxts.jpg", //用户头像 "id": "46e0fb0066666666", //评论ID 用于回复和举报 "likeTotal": 2, //点赞数 "replyContents": [ //回复评论 { "contentText": "@智酷方程式 喜欢就回复我", //回复评论内容 "createTime": 1560158986524, //回复时间 "displayName": "神秘的前端开发", //回复的用户名 "headPortrait": "https://blz.nosdn.127.net/1/2018cosplay/fourth/tesss.jpg", //回复的用户头像 "id": "46e0fb00111111111", //回复评论的ID "likeTotal": 2, //回复评论的点赞数 "replyContents": [], //回复的回复 盖楼 "replyId": "46e0fb001ec222222222", //回复评论的独立ID,用于统计 }, { "contentText": "@智酷方程式: 威武,学习学习", "createTime": 1560407232814, "displayName": "神秘的前端开发", "headPortrait": "https://blz.nosdn.127.net/1/2018cosplay/fourth/tesss.jpg", "id": "46e0fb00111111111", "likeTotal": 0, "replyContents": [], "replyId": "46e0fb001ec222222222", } ], "replyId": "", "topicId": "46e0fb001ec3333333", } ], "curPage": 1, //当前页面 //经过ID 判断 当前用户点赞了 哪些评论 "likes": [ "46e0fb00111111111", "46e0fb001ec222222222", "46e0fb0066666666", ], "nextPage": null, //下一页 "pageSize": 20, //一页总共多少评论 "total": 7, //总共多少页面 }, "msg": "success", "status": "success" }
<!-- HTML 部分 --> <block wx:if="{{commentList.length>0}}"> <!-- 评论模块 --> <block wx:for="{{commentList}}" wx:for-item="item" wx:for-index="index" wx:key="idx"> <view class="commentItem" catchtap="_goToReply" data-contentid="{{item.id}}" data-replyid="{{item.id}}" data-battle-tag="{{item.displayName}}"> <view class="titleWrap"> <image class="logo" src="{{item.headPortrait||'默认图'}}"></image> <view class="authorWrap"> <view class="author">{{item.displayName}}</view> <view class="time">{{item.createTime}}</view> </view> <view class="starWrap" catchtap="_clickLike" data-index="{{index}}" data-like="{{item.like}}" data-contentid="{{item.id}}" data-topicid="{{item.topicId}}"> <text class="count">{{item.likeTotal||""}}</text> <view class="workSprite icon {{item.like?'starIconHasClick':'starIcon'}}"></view> </view> </view> <view class="text"> {{item.contentText}} </view> </view> <!-- 评论的评论 --> <block wx:for="{{item.replyContents}}" wx:for-item="itemReply" wx:for-index="indexReply" wx:key="idxReply"> <view class="commentItem commentItemReply" catchtap="_goToReply" data-contentid="{{itemReply.id}}" data-replyid="{{item.id}}" data-battle-tag="{{itemReply.displayName}}"> ... 和上面相似 </view> </block> </block> <!-- 加载更多loading --> <block wx:if="{{isOver}}"> <view class="more">评论加载完成</view> </block> </block>
经过node提供一个API接口,经过用户的openId来判断是否点赞,这里提供一个参考的JSON结构。
JSON尽可能作成array循环的结构方便渲染,根据ID来BAN人和管理。底部加上加载更多的效果,同时,记得作一些兼容,好比默认头像等。小程序
这里建议不少交互若是不是必需要特别定制,能够才用微信原生的组件,效果和兼容性都有保障,并且方便简单。segmentfault
<!-- HTML部分 经过绑定事件:_goToReply 进行交互--> <view class="commentItem" catchtap="_goToReply" data-contentid="{{item.id}}" data-replyid="{{item.id}}" data-battle-tag="{{item.displayName}}"> ... 内部省略 </view>
//JS部分 微信原生wx.showActionSheet 显示操做菜单交互 _goToReply(e) { // 上面的各类受权判断省略... let self = this; wx.showActionSheet({ itemList: ['回复', '举报'], success: function (res) { if (!res.cancel) { console.log(res.tapIndex); //前往评论 if (res.tapIndex == 0) { //判断是不是 评论的评论 self._goToComment(replyid); } //举报按钮 if (res.tapIndex == 1) { //弹出框 self.setComplain(contentid); } } else { //取消选择 } }, fail(res) { console.log(res.errMsg) } }); } //当选择“举报”的时候,二次调用 wx.showActionSheet 方法 setComplain(contentid){ let complainJson = ["敏感信息", "色情淫秽", "垃圾广告", "语言辱骂", "其它"]; wx.showActionSheet({ itemList: complainJson, success: async res => { if (!res.cancel) { //选择好后,提交举报 try { let complainResult = await request.postComplainReport(complainJson[index], openid, contentid); if (complainResult.msg == "success") { //提交成功后反馈 } else { } } catch (e) { console.log(e) } } } }); }
显示操做菜单 wx.showActionSheet 方法说明数组
属性 | 类型 | 说明 |
---|---|---|
itemList | Array.<string> | 按钮的文字数组,数组长度最大为 6 |
itemColor | string | 按钮的文字颜色 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
使用这个方法,便是主流的作法,也能很好的兼容不一样机型,同时给予用户“习惯性体验”。浏览器
<!-- picker组件 html部分--> <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}"> <view class="picker"> 当前选择:{{array[index]}} </view> </picker>
// js部分 Page({ data:{ //查看评论类型切换 array: ["最佳", "最新", "只看本身"], //选择数组中的第几个显示 index:0 }, bindPickerChange(e) { console.log('picker发送选择改变,携带值为', e.detail.value) this.setData({ index: e.detail.value }) } })
picker组件是一个从底部弹起的滚动选择器,这里咱们用它来切换不一样评论的排序。每次切换均可以经过 bindchange得到对应的变化,经过 e.detail.value获取用户选择的索引值。
官方文档:
https://developers.weixin.qq....微信
let uriData = { logo: "xxx.jpg", type: "commentReply", title: "文章:小程序评论,动态发帖开发指北\n 做者:智酷方程式", openId:"xxxxxxxxxxx", replyId:"aaaaaa" //用户回复的是哪一个评论的ID }; wx.navigateTo({ url: `/components/plugins/comment/submit/index?uriData=${encodeURIComponent(JSON.stringify(uriData))}` });
这个能够用encodeURIComponent的方式处理下参数中的中文,避免跳转发布评论页接收数据时出现乱码。
显示和控制评论的字数
<!-- html部分 关于textarea 的配置 --> <view class='feedback-cont'> <textarea auto-focus="true" value="{{replyName}}" maxlength="200" bindinput="textareaCtrl" placeholder-style="color:#999;" placeholder="留下评论,共同窗习,一块儿进步" /> <view class='fontNum'>{{content.length}}/200</view> </view> <view class='feedback-btn' bindtap='commentSubmit'>提交</view>
// js部分 Page({ data: { //初始化评论内容,若是是回复则经过传参变成 @xxxx的形式 content: "@xxxx", }, textareaCtrl: function (e) { if (e.detail.value) { this.setData({ content: e.detail.value }) } else { this.setData({ content: "" }) } } })
textarea 在小程序中改动不大,这个标签原有的一些属性均可以继续使用,经过配置maxlength来控制字数,同时,设置auto-focus="true"可让用户进到这个发表评论页面时自动弹出虚拟键盘和光标定位在输入的区域。
固然,也能够将发表评论和评论展现区域作在一块儿,这个就要考虑到要么经过“小程序API”获取键盘高度,要么将“发布评论”置顶区域显示,也是能够作的,只是相对考虑的点会多些。当时开发评论组件的时候,考虑开发时间短和用户体验,权衡后,最终决定以上方案,但愿能给到你们一些参考和借鉴,在其余组件开发中举一反三。
demo的微信路径:https://developers.weixin.qq....
demo的ID:oHs5cMma7N9W
若是你装了IDE工具,能够直接访问上面的demo路径
经过代码片断将demo的ID输入进去也可添加:
总结,“组件化思想”对于不管作小程序、react/VUE仍是其余项目来讲,减小重复开发,提升复用性都是一个很是重要的点。评论功能其实只要理清楚总体思路,作起来难度并不大,经过一些原生组件,能够大大提升开发效率,同时保证良好的兼容性。
后面一期还将分享下功能点较多的发帖组件开发。
往期回顾:
[[[打怪升级]小程序评论回复和发贴功能实战(二)](https://segmentfault.com/a/11...
[[填坑手册]小程序Canvas生成海报(一)](https://segmentfault.com/a/11...
[[拆弹时刻]小程序Canvas生成海报(二)](https://segmentfault.com/a/11...
[[填坑手册]小程序目录结构和component组件使用心得](https://segmentfault.com/a/11...