内容简介:实现文章的一些操作功能,最主要的还是评论,这是作者和读者之间沟通的桥梁,评论功能的衍生无非是细化作者和读者之间的互动,或者增加文章的传播,所以在动手开发时需要思考下你期望实现哪些功能,并对应功能进行细化。我一般的经验是,先在脑子里过一遍需要的功能和大致流程,然后在笔记稍微画下「最最基础的原型,相当于产品的角色」。
mini-blog
的详情页的功能按钮基本已经全部实现(除了生成海报功能),这里记录下整个实现过程和实际编码中的一些坑。
实现思路
实现文章的一些操作功能,最主要的还是评论,这是作者和读者之间沟通的桥梁,评论功能的衍生无非是细化作者和读者之间的互动,或者增加文章的传播,所以在动手开发时需要思考下你期望实现哪些功能,并对应功能进行细化。
我一般的经验是,先在脑子里过一遍需要的功能和大致流程,然后在笔记稍微画下「最最基础的原型,相当于产品的角色」。
然后就开始直接开始搭建页面和简单的交互「使用假数据,优先完成页面」,在构造页面的时候其实也能够补充最初想法上一些流程上的缺陷,这样在设计后端和数据库结构的时候可以补上,整体下来也基本比较完善了。
回头看我的小程序的需求,首先肯定是操作,在文章底部需要有个操作栏,用于发送点评和其他一些操作,在参考了一些同类型的小程序之后,逐步实现自己的一套风格,样式截图如下:
在有了功能之后,点评的数据需要有地方展示「通常是文章底部」,然后就有了文章底部的评论列表,样式如下:
既然有 点赞
和 收藏
的功能按钮,是否用户需要看下我点赞和收藏的文章列表呢,所以在「我的」中就有相应的列表,样式如下:
到这里,最最基础的功能基本差不多,接下来就要看后端是否能支持这些页面了「主要就是数据的保存和展示了」
对于评论来说,肯定需要一个集合用于保存用户的评论,而对于用户的喜欢和收藏也需要一个集合来进行保存。
所以根据页面我们就可以设计 mini_comments
和 mini_posts_related
两个集合。前者用于保存评论数据,后者用户保存用户操作与文章之间的关联。
剩下的工作就是变现了,无非就是页面交互和数据的增删改查了。
细节点解析
关于评论数量
目前在文章的集合中有个 totalComments
这个属性,当这篇文章每新增一个评论时,需要加1。
最初在写这个的时候,每次都是先查再更新,两段式,原代码如下:
let count=post.totalComments+1; let result =await db.collection('mini_posts').doc(event.commentContent.postId).update({ data: { totalComments: count } });
后来看文档发现,可以使用 db.command.inc
这个指令,无需再查一遍,直接可对原字段加1,还能保证原子性。代码如下:
const _ = db.command let result = db.collection('mini_posts').doc(event.commentContent.postId).update({ data: { totalComments: _.inc(1) } });
关于新增子评论
需要实现在某个评论下进行回复。
在交互上,点击评论者的昵称或头像时,触发相应的点击事件,在事件中去记录相应的评论ID及必要数据,同时去设置焦点到评论框内:
/** * 点击评论内容回复 */ focusComment: function (e) { let that = this; let name = e.currentTarget.dataset.name; let commentId = e.currentTarget.dataset.id; let openId = e.currentTarget.dataset.openid; that.setData({ commentId: commentId, placeholder: "回复" + name + ":", focus: true, toName: name, toOpenId: openId }); },
利用云开发新增子评论时可以使用 db.command.push
来进行操作「更新指令,对一个值为数组的字段,往数组尾部添加一个或多个值」,往子评论集合中新增:
/** * 新增子评论 * @param {} event */ async function addPostChildComment(event) { let task = db.collection('mini_posts').doc(event.postId).update({ data: { totalComments: _.inc(1) } }); await db.collection('mini_comments').doc(event.id).update({ data: { childComment: _.push(event.comments) } }) await task; }
关于判断是否已收藏
在文章第一次加载时,我们需要判断下该用户是否有对该文章有相关操作,如果有相应的收藏和点赞操作,在初始化时需要更新相应的功能图标,核心代码如下:
/** * 获取收藏和喜欢的状态 */ getPostRelated: async function (blogId) { let where = { postId: blogId, openId: app.globalData.openid } let postRelated = await api.getPostRelated(where, 1); let that = this; for (var item of postRelated.data) { if (config.postRelatedType.COLLECTION === item.type) { that.setData({ collection: { status: true, text: "已收藏", icon: "favorfill" } }) continue; } if (config.postRelatedType.ZAN === item.type) { that.setData({ zan: { status: true, text: "已赞", icon: "appreciatefill" } }) continue; } } },
至于其他一些交互细节和代码细节,可以自行阅读源码去体会,如果有任何疑问或者有更好的实现方式,也可以与我沟通。
总结
这里主要想分享实现一个功能时候的过程,有想法的时候如何一步步去成功变现。
小程序本身不难,相应的文档也很详细,但是组装的过程和逻辑的实现需要自身去思考和体会。
如果你的想法和流程都非常清晰,但还是没办法实现你的预期功能,那我建议你先放放,先把 html
, css
, javascript
熟悉下,再看几遍小程序的文档,也许你当时面临的问题就不再是问题了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Essential C++中文版
李普曼 (Stanley B.Lippman) / 侯捷 / 电子工业出版社 / 2013-8-1 / CNY 65.00
本书以四个面向来表现C++的本质:procedural(面向过程的)、generic(泛型的)、object-based(基于对象的)、objectoriented(面向对象的)。全书围绕一系列逐渐繁复的程序问题,以及用以解决这些问题的语言特性来组织。循此方式,你将不只学到C++的功能和结构,也可学到它们的设计目的和基本原理。 本书适合那些已经开始从事软件设计,又抽不出太多时间学习新技术的程......一起来看看 《Essential C++中文版》 这本书的介绍吧!
在线进制转换器
各进制数互转换器
UNIX 时间戳转换
UNIX 时间戳转换