我做了一个成语接龙小程序。
我是一名安卓程序员,以前没有接触过前端开发,直到有幸接手了公司的小程序项目。小程序学起来还是很快的,对于有编程经验的人,看着示例代码,对照着官方文档,几天就能上手了。
自从接触了小程序,一直想做一个自己的东西,要是每天有点人用就更好了。
有一天和我家宝宝玩成语接龙,突然想到,我可以做一个成语接龙的小程序啊!
产品
琢磨了两天,大概想做成这样:
-
接龙可以有「所有人可参与」、「指定群成员参与」等类型
-
不校验是否是成语,否则就无法使用「印贼做父」了
-
成语的读音,还是要校验一下的
-
难免会有人乱填,所以每条成语可以赞,也可以踩
-
在有一定数据量后可以增加排行榜
设计
想法有了,还有两件比较棘手的事:
-
起个牛逼的名字
-
求我家宝宝给我画设计图
我想过很多名字,「成语接龙吧」、「接下去」、「接吧」、「接一个」...
宝宝:low 爆了,叫「碰词」,碰也有接的意思,成语也是个词嘛
这么 6 的名字居然有人先想到了,于是最终决定用「碰词er」
随便放两张设计图,美如画啥的就不说了:
下面说一下在开发方面,几个我认为值得一提的地方。
获取用户信息
现在大部分的小程序都是一打开,就弹出用户信息授权框,有的甚至强制需要授权才可使用。我之前做的一个也是需要拿到 unionId 去登录才能使用的,为此我还写过一篇文章说明如何实现。
但显然,微信认为这是一个很不好的体验。在用户没有接触你的小程序之前,凭什么要信任你,把自己的用户信息暴露给你。
为了规范用户信息的获取,官方出了这篇文章:获取用户信息方案介绍(FAQ 里面有两个问题还是我提的)
刚好拿这个小程序来实践一下。
首先,明确什么情况下需要用到用户信息。这里需要用户信息显示在成语旁,所以在创建接龙或者发送成语之前,需要先获取到用户信息。如果你只是进来看看,是不需要你任何授权的,只有点击了创建接龙的按钮,或者发送成语的按钮,才会弹出授权提示框。
我是这样做的。没有用户信息时,设置 button 的 open-type 为 getUserInfo,点击会触发用户信息的获取。要是已经有用户信息了,则是一个普通的跳转按钮:
<view class="create-button">
<button wx:if="{{hasUserInfo}}" class="button" bindtap="navigateToCreate">
<image class="img" src="/images/icon_add.png" mode="aspectFit"/>
</button>
<button wx:else class="button" open-type="getUserInfo" bindgetuserinfo="getUserInfo">
<image class="img" src="/images/icon_add.png" mode="aspectFit"/>
</button>
</view>
当用户确定授权了,可以在 bindgetuserinfo 绑定的方法里,用 e.detail.userInfo 拿到用户信息。
但还有个问题,open-type="getUserInfo" 要到基础库 1.3.0 才能用,最好还是做一下低版本兼容处理。
群能力
目前,小程序已经支持获取到微信群的群 id 和显示群名。
当用户创建的接龙类型是指定群成员参与时,指定的群就是第一个转发到的群。而成员也只有通过这个群的分享进入小程序,才可参与接龙。下面说说这两种情况是如何获取到群 id 的。
在可分享的页面,调用 wx.showShareMenu() 显示转发按钮。添加 onShareAppMessage 方法,并在里面设置分享信息:
onShareAppMessage: function () {
var that = this
return {
title: "一起来玩成语接龙!",
path: 'pages/xxx/xxx?id=' + this.data.id,
success(res) {
that.getShareInfo(res.shareTickets[0])
}
}
}
在 getShareInfo 方法里,需要获取到分享信息,现在能获取到的只有群 id:
wx.getShareInfo({
shareTicket: shareTicket,
success(res) {
// 解密获取到 openGId
}
})
这里和 getUserInfo 一样,拿到的数据是加密的,需要将 res.encryptedData 和 res.iv 传给后台解密。加密方式和 userInfo 是一样的,所以可以用同一个接口解密。解密后的 openGId 就是我们要的群 id。
至于从微信群进入的情况,我们需要对 app.js 的 onLaunch 方法动手。在 onLaunch 方法里可以获取到一个场景值,它区分了各种进入小程序的场景,各种场景值说明可以在这里查到。其中可以看到:
当场景值为 1044 时,我们就可能获取到携带的 shareTicket:
onLaunch: function (ops) {
if (ops != null && ops.scene == 1044) {
this.globalData.shareTicket = ops.shareTicket
}
}
之后再对这个 shareTicket 进行解密,获取 openGId,判断用户是否可参与。
聊天列表
从设计图可以看到,成语列表是置底的,类似微信聊天的效果。但列表都是默认置顶的,如何让它置底呢?
其实很简单,这里利用了 scroll-view 组件的 scroll-into-view 属性:
注意这里有个细节,id 不能以数字开头,但我的 id 就是数字开头的怎么办?前面随便加个字母就好了:
<scroll-view class="scroll" scroll-y="true" scroll-into-view="x{{toView}}">
<!-- ...... -->
</scroll-view>
item 的 id 前面也记得加个 x。
然后在获得页面数据 setData 之后,将列表定位到底部:
setTimeout(function () {
that.setData({
toView: list[list.length - 1].id
})
}, 300)
这里的延时是不可少的,因为页面渲染需要点时间,不同性能的手机需要的时间还不一样。看过几台手机,300 毫秒应该是比较合适的。
如果要实现滑动到顶部加载更多的话,可以用上 bindscrolltoupper 这个属性:
获取更多后,将 toView 设置为新获取到的列表最后一项的 id。
浮动按钮
首页右下角的按钮美如画,但是它会造成一定的遮挡。
安卓里有一个叫 FloatActionButton 的控件,当列表滚动时,可以向下移动隐藏,我尝试在小程序里实现类似的效果。
我觉得遮挡其实只对列表最底部有影响,所以当列表滚到底部时隐藏就好了,发生滚动再显示。
在不使用 scroll-view 的情况下,页面触底会触发 onReachBottom 方法,滚动会触发 onPageScroll 方法,所以这个功能可以这样实现:
js
onReachBottom: function (event) {
// 隐藏按钮,避免遮挡
this.setData({
showBtn: false
})
},
onPageScroll: function (event) {
// 显示创建按钮
this.setData({
showCreateBtn: true
})
}
wxml
<view class="button {{showBtn?'show-button':'hide-button'}}"/>
wxss
.show-button {
transform: translateY(0);
transition: 0.3s;
}
.hide-button {
transform: translateY(180rpx);
transition: 0.3s;
}
是不是很简单,效果还不错:
但是这里面有两个坑:
-
在开发工具上没什么问题,但在真机上,列表到达底部触发 onReachBottom 之后,居然还会触发 onPageScroll。我的做法是在 onReachBottom 之后的三百毫秒内不显示按钮。
-
在列表高度不满屏幕高度时,向上滑动列表,也会触发 onReachBottom,但是不会触发 onPageScroll,导致隐藏后就不会再显示了。解决方法是,可以先判断列表是否可滚动,不可滚动的情况下不隐藏按钮。
总结
刚开始,在没有推广的情况下,在我身边的人都不愿意玩的情况下,每天会有一两百个新用户。在上次知晓程序推荐过后,现在居然每天有一两千个新用户!流量费都快给不起了,非常感谢大家的捧场。
最后,感谢我家宝宝做了这么好看的设计图。
推荐阅读
-
像首席技术官一样思考:如何高效管理 30 人的研发团队?-管理越多越轻松。好的研发团队,应该是上拨下用,即下级对上级的向上管理;而不是反过来,总是向下管理,甚至是 CTO 做经理的事,经理做工程师的事,工程师最终会被当成实习生。如果是这样,就会越管越累,不仅团队无法成长,而且团队整天很忙还效率低下,问题一大堆。 有这样一个小故事:一位高级经理下班后帮忙倒垃圾,结果被老板训斥了一顿。这就好比首席技术官做了实习生自己该做的事。事情本身没有对错之分,只是从不同的角度有不同的理解。 古人云:"用人不疑,疑人不用"。在面对自己的研发团队时,应该相信他们能做好,授权一线开发人员充分发挥专业特长,不要限制他们的工作。但在相信他们的同时,也要进行二次确认,始终秉持 "我相信,但我要确认 "的原则和严谨的精神。因为每个人都会犯错和疏忽,通过发挥团队的智慧,团队犯错的机会就会大大减少。比如回归测试、代码审查、开发演示、变更审批等等。 如前所述,每个人都难免会犯错。但作为管理者,你所设计和商定的流程不能出错。管理者的每一个决定和沟通都应该经过深思熟虑。就像红绿灯的交通设计,某辆车不小心闯红灯可能会扣分,但红绿灯的设计一定要正确、人性化、统一。再比如,开发人员可能会因为疏忽大意写出 bug,但研发流程的设计和上线流程的发布不能有任何差错。因此,流程体系的设计,一方面要结合当前团队规模、业务特点和需要重点解决的问题来设计,另一方面也要在人员防错、效率提升、发挥团队集体智慧等维度进行综合考量。应该站在更高更抽象的角度去思考,不断思考一个倍受欢迎的园区应该如何设计,思考一个灵动、经典、永恒的建筑应该遵循怎样的模式,思考一个成功、优秀、卓越的研发团队应该需要怎样的流程和制度。 最后,反馈很重要。向上汇报很重要,向下反馈也很重要。能够保持顺畅的双向反馈和闭环管理,对研发团队的协作和沟通有着非常明显的积极作用。在向上汇报方面,要培养团队在正式汇报、会议汇报、私下沟通、书面总结、非正式场合等方面的沟通能力,提醒下属报喜也要报忧。凡事先记录,再跟进,最后反馈。反馈很重要,主动汇报更难得。 另一方面,同时也不要忽视向下反馈。好的爱,是双向的。团队也是如此,没有严格的上下级之分,只是分工和角色不同而已。作为管理者,不必总保持一种 "神秘感",让人 "捉摸不透 "才是牛。当团队做得好或有人做得好时,要记得在公开或私下场合给予肯定和赞许。业务有增长、业绩有提升时,别忘了给团队一些鼓励,或者安排一次下午茶或聚餐。在例会或正式会议上,也可以同步向大家传达一些重要信息和高层指示。"欲速则不达,欲远则同行"。 当向上汇报、向下反馈的沟通闭环形成后,同时结合前面研发过程的管理闭环,双管齐下,就能形成良性循环。如此反复,持之以恒,优秀卓越的研发团队,必将呈现。 能力、产出和效率 接下来,继续重复关于能力、产出和效率的话题。 站在不同的角色,以及一个企业经营、生存和发展所需要的基础上,我把研发生产力分为三个层次,分别是:一线员工关心的研发能力、管理层关心的软件产出和操作人员关心的企业生产效率。简单概括就是:既要把工作做好,又要能出成果,还要能帮企业赚钱。
-
我做了一个成语接龙小程序。
-
如何证明 "我就是我"?一个小程序就能解决!
-
我的第一个微信小程序 "Hello World"(超详细)--我的解决方法是使用快捷键Ctrl+shift+Esc打开任务管理器,将打开的微信开发者工具内部的所有进程关闭,然后右键点击桌面上的微信开发者工具,以管理员身份运行微信开发者工具就可以成功打开微信开发者工具登录界面了!以下是开发者创建微信开发者工具登录界面的步骤汇总
-
最近,我写了一个日常习惯时钟、个人日记、生活轨迹小程序,小程序名叫:小粽子日记