微信小程序开发完工+问题汇总 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Dmego
V2EX    微信

微信小程序开发完工+问题汇总

  •  2
     
  •   Dmego 2017-12-05 13:20:08 +08:00 3254 次点击
    这是一个创建于 2871 天前的主题,其中的信息可能已经有所发展或是发生改变。

    出发吧一起

    前言

    经过将近一个多月的开发,我们团队开发的微信小程序 "出发吧一起" 终于开发完成,现在的线上版本为 2.2.4-beta 版

    本文档主要介绍该小程序在开发中所用到的技术,已经在开发中遇到问题的采取的解决方法

    小程序简介

    “让兴趣不再孤单,让爱好不再流浪” 是微信小程序《出发吧一起》的主题,这款小程序旨在解决当代大学生在校园生活中的孤独感,让大家找到志同道合的朋友,在跑步、健身、竞赛等活动中找到伙伴。利用小程序即开即用,用完就走的特点与交友相结合,它将会是一款高效快捷、无负担的线下交友利器

    本小程序由 bmob 后端云提供数据处理与存储支持

    小程序码

    欢迎扫描体验

    开发中技术问题汇总

    1.使用 e.target.dataset 的出现问题

    在小程序开发过程中,我们经常会用到标签中属性的属性值,我们通常会在 <view> 中 设置 data-*="{{XXX}}" 然后在 JS 里通过 e.target.dateset.* 来获取XXX值,但是我经常遇到获取的是undefined,使用 console.log(e) 查看输出信息会发现,在 e对象中包含两个对象分别是currentTargettarget,而往往有些时候数据在currentTarget中,

    此时可以将代码替换成这样来获取值

    • WXML
    <view bindtap="bintap" data-id="1"></view> 
    • JS
    bintap:function(e){ var id = e.currentTarget.dataset.id; } 

    网上还有一直说法是 data-** 命名的问题,去掉驼峰式命名,纯小写也能解决

    2.小程序 textarea 文本框如何显示实时字数

    • WXML
    <view> <view> <textarea name="content" bindinput="bindTextAreaChange" maxlength="{{noteMaxLen}}" /> <view class="chnumber">{{noteNowLen}}/{{noteMaxLen}}</view> </view> </view> 
    • JS
    data:{ noteMaxLen: 200,//备注最多字数 noteNowLen: 0,//备注当前字数 } //字数改变触发事件 bindTextAreaChange: function (e) { var that = this var value = e.detail.value, len = parseInt(value.length); if (len > that.data.noteMaxLen) return; that.setData({ content: value, noteNowLen: len }) }, 

    3.利用 JS 实现模糊查询

    由于我们使用的是 Bmob 后端云提供的数据处理与存储支持,根据 Bmob 提供的开发文档,免费版的应用无法进行模糊查询,看到这里,再看看已经快完工的活动检索界面,感受无法言说。正当准备放弃的时候,突然想到一个方法,那就是先把所有的后台所有数据都存到集合里,然后根据输入的检索值一个个匹配,想到之后马上就开始着手干了,先查了一下Javascript 文档,String 对象有一个方法是 indexOf() ,可返回某个指定的字符串值在字符串中首次出现的位置,这样就成了,遍历 所以数据,检索每一条数据的每个字符,如果出现了则将它加入到检索结果的集合中.

    • JS
    //js 实现模糊匹配查询 findEach: function (e) { var that = this var strFind = that.data.wxSearchData.value; //这里使用的 wxSearch 搜索 UI 插件, if (strFind == null || strFind == "") { wx.showToast({ title: '输入为空', icon: 'loading', }) } if (strFind != "") { var nPos; var resultPost = []; for (var i in smoodList) { var sTxt = smoodList[i].title || ''; //活动的标题 nPos = sTxt.indexOf(strFind); if (nPos >= 0) {//如果输入的关键字在该活动标题中出现过,则匹配该活动 resultPost.push(smoodList[i]); //将该活动加入到搜索到的活动列表中 } } that.setData({ moodList: resultPost }) } }, 

    更加详细的代码请前往Github查看

    4.使用 JS 将字符串格式的时间转换成几秒前,几分钟前...

    由于小程序中涉及评论,加入活动,收藏等一系列包括事件时间的功能,而数据库中存的时间格式为 2017-11-30 23:36:10 现在想要在界面上不显示具体时间,而是显示与当前时间的差,即几秒前,几分钟前等等

    实现起来并不复杂,主要思路是先把字符串的时间转换成时间戳,然后与当前的时间戳进行比较,这样就能转换成几秒前、几分钟前、几小时前、几天前等形式了

    • JS
    //字符串转换为时间戳 function getDateTimeStamp(dateStr) { return Date.parse(dateStr.replace(/-/gi, "/")); } //格式化时间 function getDateDiff(dateStr) { var publishTime = getDateTimeStamp(dateStr) / 1000, d_seconds, d_minutes, d_hours, d_days, timeNow = parseInt(new Date().getTime() / 1000), d, date = new Date(publishTime * 1000), Y = date.getFullYear(), M = date.getMonth() + 1, D = date.getDate(), H = date.getHours(), m = date.getMinutes(), s = date.getSeconds(); //小于 10 的在前面补 0 if (M < 10) { M = '0' + M; } if (D < 10) { D = '0' + D; } if (H < 10) { H = '0' + H; } if (m < 10) { m = '0' + m; } if (s < 10) { s = '0' + s; } d = timeNow - publishTime; d_days = parseInt(d / 86400); d_hours = parseInt(d / 3600); d_minutes = parseInt(d / 60); d_secOnds= parseInt(d); if (d_days > 0 && d_days < 3) { return d_days + '天前'; } else if (d_days <= 0 && d_hours > 0) { return d_hours + '小时前'; } else if (d_hours <= 0 && d_minutes > 0) { return d_minutes + '分钟前'; } else if (d_seconds < 60) { if (d_seconds <= 0) { return '刚刚'; } else { return d_seconds + '秒前'; } } else if (d_days >= 3 && d_days < 30) { return M + '-' + D + ' ' + H + ':' + m; } else if (d_days >= 30) { return Y + '-' + M + '-' + D + ' ' + H + ':' + m; } } 

    5.微信小程序提交表单清空表单数据

    在发布活动之后,由于表单中的数据没有清空,给用户的体验必定不好,然而小程序的数据交互并不像html + jS 那样,使用 dataSet({}) 来给赋值,视图层就能通过异步的方式活动到值,于是想到,在提交表单后,给这些input都赋值为空,那样就实现了清空表单的效果,当然,表单中并不只包含input,但是都可以通过这种方式实现清空效果

    • WXML
    <form bindsubmit="submitForm"> <text class="key">活动名称</text> <input name="title" maxlength="100" value="{{title}}" /> <button formType="submit">确定</button> </form> 
    • JS
    submitForm:function(e){ var title = e.detail.value.title; ...... success: function (res) { //将 title 值设置空 that.setData({ title: '' } } } 

    6.微信号,QQ 号,手机号 正则校验

    由于申请加入活动需要填写真实姓名,联系方式等信息,为了防止用户随意填写信息,必须要对这些信息进行校验

    • JS
     var wxReg = new RegExp("^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$"); //微信号正则校验 var qqReg = new RegExp("[1-9][0-9]{4,}"); //QQ 号正则校验 var phReg = /^1[34578]\d{9}$/; //手机号正则校验 var nameReg = new RegExp("^[\u4e00-\u9fa5]{2,4}$"); //2-4 位中文姓名正则校验 

    7.使用 Bmob SDK 实现报名成功发送模板消息,生成小程序二维码等

    在开发过程中,由于想要实现,当用户报名成功后如何通知用户,查阅了小程序的开发文档发现有一个发送模板消息的 API,再查询 Bmob 的开发文档,发现实现了这个功能,这个真的太有用了.模板消息只能再真机上才能发送成功,经过配置,重要成功,但是有在使用中出现一个问题 ,就是在小程序发布后 模板消息中如果带有 page 参数将不会发送,但是在开发版中能发送成功, 这个问题已经反馈了,估计等 Bmob 小程序SDK更新后会解决这个问题.

    具体代码我就不写了,bmob 开发文档直达

    截图 & GIF

    启动画面

    消息通知

    地图模式.gif

    Bmob 数据库表结构设计

    用户表:(_User,自带表)

    |--objectId //Id |--userPic(String) //用户头像 |--username(String) //用户名 |--password(String) //密码 |--nickname(String) //昵称 |--sex(Number) //性别 |--userData(Object) //微信登录用户数据 |--eventJoin(Array) //参加的活动 Id 数组 Array |--eventFavo(Array) //收藏的活动 Id 数组 Array |--feednum(Number) //反馈次数 

    活动信息表:(Events)

    |--objectId //活动 Id |--publisher(Pointer-->_User) //发起人 |--title(String) //活动主题 |--content(String) //活动内容 |--actpic(File) //活动宣传照片 |--acttype(String) //活动类别 { 1:运动,2:游戏,3:交友, 4:旅行,5:读书,6:竞赛, 7:电影,8: 音乐,9: 其他 } |--isShow(Number) //是否公开显示在首页 |--endtime(String) //组队截止时间 |--address(String) //活动地点 |--latitude(Number) //地址纬度 |--longitude(Number) //地址经度 |--peoplenum(String)//人数限制 |--likenum(Number) //点赞数 |--liker(Array) //点赞人 Id 集合 |--commentnum(Number) //评论数 |--joinnumber(Number) // 现在参加的人数 |--joinArray(Array) // 现在参加的人集合 

    活动信息扩展表:(EventMore)

    |--objectId //活动信息扩展表 Id |--event(Pointer-->Events) //活动 |--Status(Number) //活动状态,(1:准备中,2:进行中,3:已结束) |--Statusname(String) //活动状态名称 |--qrcode(File) //活动群聊二维码 

    评论表:(Comments)

    |--objectId //评论 Id |--publisher(Pointer-->_User) //评论发布者 |--olderUsername(String) //上一条评论人昵称 |--olderComment(Pointer-->Comments) //上一条评论 |--event(Pointer-->Events) //评论的活动 |--content(String) //评论内容 

    点赞表:(Likes)

    |--objectId //点赞的 Id |--liker(Pointer-->_User) //点赞人 |--event(Pointer-->Events) //点赞的活动 

    收藏表:(Favos)

    |--objectId //收藏的 Id |--favor(Pointer-->_User) //收藏者 |--event(Pointer-->Events) //收藏的活动 

    消息通知表:(Plyre)

    |--objectId //消息通知的 Id |--fid(String) //活动发布者 Id(被赞或者被取消赞的人的 ID,或者被回复,被评论的人的 ID)(被通知的人) |--uid(Pointer-->_User) //消息通知人 |--wid (String) //被赞,或者取消赞,被评论,或者被回复,加入,取消加入的活动 id |--avatar (String) //消息通知人的头像 |--username (String) //消息通知人的姓名 |--is_read(Number) //这条消息是否已读( 1 代表已读,0 代表未读) |--bigtype(Number) //消息通知大类(1 代表消息,2 代表通知) |--behavior(Number) //(消息提醒类型) { 1:赞 2:取消赞 3:被评论 4:被回复 5:加入活动 6:取消加入活动 7:修改了加入信息 } 

    活动联系表:(Contact)

    |--objectId //联系表 Id |--publisher(Pointer-->_User) //活动发布者 |--currentUser (Pointer-->_User) //当前用户 |--event(Pointer-->Events) //想要加入的活动 |--realname (String) //真实姓名 |--contactWay(String) //联系方式(微信号,手机号,QQ 号) |--contactValue(String) //联系方式的号码 

    反馈表:(Feedback)

    |--objectId //反馈 Id |--feedUser(Pointer-->_User) //反馈人 Id |--title(String) //反馈标题 |--content(String) //反馈内容 |--feedpic(File) //反馈图片 |--feedinfo(String) //反馈用户的设备信息 
    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2897 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 13:54 PVG 21:54 LAX 06:54 JFK 09:54
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86