当前位置: 首页 > 后端技术 > Node.js

用小程序云开发打造功能齐全的博客小程序丨实践

时间:2023-04-03 21:22:32 Node.js

使用小程序云开发“一网打尽博客小程序常用功能”评论、点赞、收藏、发帖功能,下面是整个实现中的一些坑过程和实际编码。评论、点赞、收藏实现。实现了文章的一些操作功能。最重要的是评论。这是作者与读者沟通的桥梁。增加文章的传播,所以需要在开始开发的时候想好自己期望实现什么功能,细化对应的功能。我一般的经验是先在脑海里过一遍需要的功能和大概的流程,然后在笔记中画出一点“最基本的原型,相当于产品的作用”。然后直接开始构建页面和简单交互“使用假数据,先完成页面”。在构建页面的时候,其实可以补充一下原来思路中的一些流程缺陷,这样在设计后台和数据库结构的时候,可以把它加起来,整体就基本完美了。回顾一下我的小程序的需求,首先肯定是运营。文章底部需要有一个操作栏,用于发送评论等操作。在参考了一些同类型的小程序之后,我会慢慢的体会到自己的一套风格,样式截图如下:功能开启后,评论数据需要有个地方显示“一般在文章底部”,然后在文章底部会有一个评论列表article,样式如下:由于有点赞和收藏的功能按钮,用户是否需要查看我点赞和收藏的文章列表,所以在“我的”中有对应的列表,样式如下:这里,最基本的功能基本都差不多,接下来就是看后台能不能支持这些页面了,“主要是数据的存储和展示”。对于评论来说,肯定需要一个集合来保存用户的评论,还需要一个集合来保存用户的点赞和收藏。所以根据页面,我们可以设计两组mini_comments和mini_posts_related。前者用于保存评论数据,后者用于保存用户操作与文章的关联。剩下的工作就是实现了,无非就是页面交互和数据的增删改查。评论数详解目前文章集合中有一个属性totalComments。当有新的评论被添加到这篇文章时,它需要增加1。第一次写这个的时候,每次都是先检查再更新。原代码如下:letcount=post.totalComments+1;letresult=awaitdb.collection('mini_posts').doc(event.commentContent.postId).update({data:{totalComments:count}});看了文档,发现db.command.inc这个命令不用再查就可以用了。可以直接在原字段上加1,返回的原子性是有保证的。代码如下:const_=db.commandletresult=db.collection('mini_posts').doc(event.commentContent.postId).update({data:{totalComments:_.inc(1)}});关于添加子评论,需要在某个评论下实现回复。在交互方面,当评论者的昵称或头像被点击时,会触发相应的点击事件,并在事件中记录相应的评论ID和必要的数据,同时将焦点设置到评论框:/***点击评论内容回复*/focusComment:function(e){letthat=this;letname=e.currentTarget.dataset.name;letcommentId=e.currentTarget.dataset.id;letopenId=e.currentTarget.dataset.openid;that.setData({commentId:commentId,placeholder:"Reply"+name+":",focus:true,toName:name,toOpenId:openId});},使用云开发添加新的子注释时,可以使用db.command.push来操作“updatecommand,对于值为数组的字段,在数组末尾添加一个或多个值”,并添加到子评论集合:/***添加子评论*@param{}event*/asyncfunctionaddPostChildComment(event){lettask=db.collection('mini_posts').doc(event.postId).更新({数据:{totalComments:_.inc(1)}});awaitdb.collection('mini_comments').doc(event.id).update({data:{childComment:_.push(event.comments)}})awaittask;}about时判断文章是否有首次采集,需要判断用户是否对文章进行过相关操作。如果有对应的收藏之类的操作,需要在初始化时更新对应的功能图标。核心代码如下:/***获取收藏和点赞的状态*/getPost相关:异步函数(blogId){letwhere={postId:blogId,openId:app.globalData.openid}letpostRelated=awaitapi.getPostRelated(where,1);letthat=this;for(postRelated.data的varitem){if(config.postRelatedType.COLLECTION===item.type){that.setData({collection:{status:true,text:"Favorite",icon:"favorfill"}})continue;}if(config.postRelatedType.ZAN===item.type){that.setData({zan:{status:true,text:"Like",icon:"appreciatefill"}})continue;}}},至于其他交互细节和代码细节,大家可以阅读源码自行体会。如果大家有什么问题或者有更好的实现方式,也可以和我交流海报功能,说明一些背景,在最早的小程序中已经实现过一次。详细可以参考使用云开发优化博客小程序(三)-生成海报功能,主要是利用原来的cavans进行拼装。本来是想复制代码改改的。改一下就好了,但是总觉得原来的代码写得不是特别好。于是想看看有没有现成的轮子可以用,找到了wxa-plugin-canvas这个组件,通过非常简单的配置就可以生成漂亮的海报。小程序使用npm在总结生成海报的功能之前,还是有必要记录下小程序npm的使用,以免误入不必要的坑。考虑到小程序本身的大小限制,使用npm的方式是最好的。原因是根据官方文档,只有小程序npm包中的build文件生成目录才会被计入小程序包占用的空间,上传小程序代码时只会上传该目录下的代码。这大大减少了上传的代码大小。下面简单介绍一下如何在小程序端使用npm。“其实按照官方文档的步骤就可以了。”以我现在的小程序所在路径为例,在/miniprogram中新增文件夹node_modules,在命令行中指向/miniprogram目录:通过命令安装:npminstallwxa-plugin-canvas--production安装完成后成功后,就可以在小程序开发工具中进行Build了。构建前需要勾选npm模块的使用,然后在开发者工具中点击菜单栏:Tools-->Buildnpm:构建完成后会生成miniprogram_npm目录。到这里,项目端基本就调好了,wxa-plugin-canvas搭建完成后,自定义组件wxa-plugin-canvas就可以正常使用了,使用方法也比较简单。先在你需要的页面引入组件:{"usingComponents":{"poster":"wxa-plugin-canvas/poster"}}然后就可以在wsml中使用了:因为我们正在生成海报之前海报需要异步获取一些数据,所以我们采用异步生成海报的方式。需要导入组件的poster/poster.js文件,然后在代码中调用:importPosterfrom'../../utils/poster';Page({/***异步生成海报*/onCreatePoster(){//setData配置数据this.setData({posterConfig:{...}},()=>{Poster.create();});}})核心代码分析海报所需数据我们先来看一下共享海报的整体结构:首先需要确认海报的构成需要哪些数据,并获取调用组件前的相应数据。我设计的海报主要包含三块内容,用户信息(头像和昵称),文章信息(首图,标题,介绍)和最重要的文章小程序代码。用户信息和文章信息其实都比较简单,小程序详情页都有这两个数据,但是有两个问题需要注意。第一个是域名问题。画布中使用的图片需要配置域名,头像域名和公众号文章第一张图片的域名https://mmbiz.qpic.cnhttps://wx.qlogo.cnSecondOne是公众号第一张图的问题。公众号的素材列表返回的图片url其实是http,但是小程序绑定的域名必须是https。那时,我很无助。后来尝试用https访问第一张图片。url也是可以的,幸好,所以在使用第一张图片的地址时替换掉:imageUrl=imageUrl.replace('http://','https://')最后就是小程序代码了文章中,需要使用小程序的getUnlimitedapi,具体可以参考官方文档。目前已经提供云调用“无需获取access_token”的方法,调用比较简单。原计划在文章同步时,“adminService”直接生成文章对应的小程序代码。代码写好后,可以进行本地调试,但是上传到云端后,测试发现一直报错。不支持云调用,所以这个计划落空了,我在代码中打了一个TODO。这样的话,就在生成海报的时候生成,生成后直接上传到云存储,并把对应的FileID保存到文章集里,这样只生成一次就可以一直使用了。具体代码如下:/***新文章二维码*@param{}event*/asyncfunctionaddPostQrCode(event){letscene='timestamp='+event.timestamp;letresult=awaitcloud.openapi.wxacode.getUnlimited({scene:scene,page:'pages/detail/detail'})if(result.errCode===0){letupload=awaitcloud.uploadFile({cloudPath:event.postId+'.png',fileContent:result.buffer,})awaitdb.collection("mini_posts").doc(event.postId).update({data:{qrCode:upload.fileID}});letfileList=[upload.fileID]letresultUrl=awaitcloud.getTempFileURL({fileList,})returnresultUrl.fileList}return[]}不过这里有个尴尬的地方,生成小程序代码的API中场景参数的最大长度是32,但是文章id的长度已经是32,无法根据文章id拼接跳转页面的路径,所以这里暂时使用了mini_posts集合中的timestamp字段,“理论上唯一”。所以也需要兼容详情页中的timestamp字段。海报图片展示海报图片展示比较简单,使用弹窗展示生成的海报图片:/***海报生成成功-回调*@param{}e*/onPosterSuccess(e){const{detail}=e;this.setData({posterImageUrl:detail,isShowPosterModal:true})console.info(detail)},保存海报图片,保存图片使用wx.saveImageToPhotosAlbum调用用户相册,这里主要需要兼容一些用户拒绝相册授权的系列操作,具体代码如下:/***保存海报图片*/savePosterImage:function(){letthat=thiswx.saveImageToPhotosAlbum({filePath:that.data.posterImageUrl,success(result){console.log(result)wx.showModal({title:'提示',content:'二维码海报已存入手机相册,快点上传并分享到朋友圈',showCancel:false,success:function(res){that.setData({isShowPosterModal:false,isShow:false})}})},fail:function(err){console.log(err);if(err.errMsg==="saveImageToPhotosAlbum:failauthdeny"){console.log("再次发起授权");wx.showModal({title:'用户未授权',content:'如果要将海报图片保存到相册,需要获得授权。是否选择授权管理中的“保存到相册””?',showCancel:true,success:function(res){if(res.confirm){console.log('用户点击确定')wx.openSetting({success:functionsuccess(res){console.log('打开设置',res.authSetting);wx.openSetting({success(settingdata){console.log(settingdata)if(settingdata.authSetting['scope.writePhotosAlbum']){console.log('获取相册保存权限成功');}else{console.log('获取相册保存权限失败');}}})}});}}})}}});}、经验总结有不错的开源组件可以补单独使用,避免重新发明轮子。有机会也可以借鉴别人的实现方法,多看文档。其实小程序的文档真的很详细。这里主要是想分享一下实现一个功能的过程,有想法的时候是如何一步步成功实现的。小程序本身并不难,相应的文档也很详细,但是组装过程和逻辑实现需要自己去思考和体验。多看文档,其实小程序的文档真的很详细。如果你的思路和流程已经很清楚了,但是还是不能实现你想要的功能,那我建议你先放手,熟悉html,css,javascript,然后多看几遍小程序的文档,说不定你当时面临的问题已经不是问题了。源码链接https://github.com/TencentCloudBase/Good-practice-tutorial-recommended如果您有使用云开发CloudBase的技术故事/技术实践经验想分享给大家,欢迎留言联系我们~比心!