# wxapp-cnode **Repository Path**: hayeah/wxapp-cnode ## Basic Information - **Project Name**: wxapp-cnode - **Description**: 微信小程序直播 - wxapp-cnode - **Primary Language**: 微信 - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 129 - **Forks**: 22 - **Created**: 2016-09-29 - **Last Updated**: 2025-04-26 ## Categories & Tags **Categories**: weixin-lapp **Tags**: None ## README # 直播地址 live.bilibili.com/1330246 9/30 周五 8 点开播 # 带你实现小程序 CNode 社区 ## 讲师介绍 主驾驶老司机:桑世龙 简介:江湖传说的狼叔,是空弦科技 CTO。开源项目 Moajs 作者,Node.js 技术布道者。 正在写一个本新书《更了不起的 Node 4:将下一代 Web 框架 Koa 进行到底》 副驾驶老司机:叶倍宏 简介:前自由职业者,远程办公,边旅行边工作,在云南大理住了 2 年。现在来广州发展思客教学,做有情怀的 IT 教学。 # 微信小程序是什么? 先回顾一下微信应用号发布事件 传闻已久的微信应用号终于得到证实。21日晚间,微信公众号“小道消息”发布文章称收到微信官方的微信应用号内测邀请。根据内测邀请函显示,应用号是微信公众平台提供了一种新的开放能力,开发者可以快速开发一个小程序。 有腾讯内部员工在职场社交软件脉脉上爆料:应用号以“微信公众平台小程序”的名义进行内测发布,核心功能是提供一些本地的API供H5上面的js调用,以此提升微信上H5应用的流畅度。 据爆料,根据腾讯内部数据筛选,第一批应用号内测只邀请了200个微信公众号,若还想收到邀请的公众号只能等待下一批。 早在今年年初,“微信之父”张小龙就透露出正在打造应用号的消息,而后张小龙便在2016年微信公开课PRO上,第一次正式对外公布应用号。 什么是应用号?张小龙介绍说,当用户关注了一个「应用号」之后,就相当于安装了一款 app。在「应用号」内,用户就可以实现对 app 的一些基本诉求。例如,目前许多用户会选在微信钱包中可以买机票、火车票,而不是去下载一个并不常用的买票软件;未来在「应用号」中,可以实现更多的功能。并和其他 app 一样,这个公众号平时是不会向用户主动发送内容的,因此会避免打扰。 据张小龙介绍,推出应用号基于两方面的原因。一是用户手机上可以少下载安装一些软件,平时打开频率不高的软件,可以用应用号代替;二是用户换手机时无需重复安装软件。而对于开发者,尤其是创业者来说,在应用号中实现一个功能远比开发一款 app 省钱省力许多。 一句话简介 > 微信小程序是限于微信提供的MINA框架提供的app开发便捷展示解决方案 # 实例:用cnode社区api做微信小应用 https://github.com/coolfishstudio/wechat-webapp-cnode ## Why? 一次只做一件事儿,已有api,你只需要关注小程序 切莫贪多, ## 导入项目 添加项目 ![1](images/import/1.png) 选择源码所在目录 ![2](images/import/2.png) 完整信息 ![3](images/import/3.png) ## 首页 效果 ### 布局 ![Layout](images/layout.png) example/pages/topics/topics.wxml ``` 全部 精华 分享 问答 招聘 {{item.author.loginname}} 置顶 精华 {{item.last_reply_at}} {{item.title}} {{item.reply_count}} {{item.visit_count}} ``` 三大部分 - top-bar 分类是普通的view - posts-list 帖子列表,是scroll-view - loading 内置的组件,默认隐藏 > 简单点说,就是你们误会了的组件 是不是跟vue、react很像? http://wxopen.notedown.cn/component/ ![Component](images/component.png) ### 帖子列表 ``` {{item.author.loginname}} 置顶 精华 {{item.last_reply_at}} {{item.title}} {{item.reply_count}} {{item.visit_count}} ``` 布局是scroll-view,然后嵌入了 ``` ``` 像不像ejs里的 ``` ``` 然后我们看看里面的单条展示 ![Cell](images/cell.png) ``` {{item.author.loginname}} 置顶 精华 {{item.last_reply_at}} {{item.title}} {{item.reply_count}} {{item.visit_count}} ``` 可以看出是一个cell里分了3行 - 第1行 author 作者、时间 - 第2行 posts-title 标题 - 第3行 bar-info 评论,查看次数 然后单行,以author为例子 ``` {{item.author.loginname}} 置顶 精华 {{item.last_reply_at}} ``` 各位看到这里有啥感觉呢? ### 如何获取数据? 上面模板里的`for` + 描述用的block,有一个postsList,如果有它就可以显示了。那么如何它在哪里呢? 其实在example/pages/topics/topics.js里的 ``` Page({ data: { title: '话题列表', postsList: [], hidden: false, page: 1, tab: 'all' }, ... }) ``` 注意data里的postsList。也就是说data里的面内容会和模板一起编译,有木有明白点什么? ### 和模板引擎像么? 模板引擎原理 > 编译(模板 + 数据)= html 你只要setData,它就会自动渲染,是不是有点像mvvm?$scope? ``` self.setData({ postsList: self.data.postsList.concat(res.data.data.map(function (item) { item.last_reply_at = util.getDateDiff(new Date(item.last_reply_at)); return item; })) }); ``` 只不过所有的数据都放到data作为上下文,这其实是简化了的方案。 ### http请求 api是获取主页列表 ![Api](images/api.png) 具体的调用wx.request向服务器发送 ``` wx.request({ url: Api.getTopics(data), success: function (res) { self.setData({ postsList: self.data.postsList.concat(res.data.data.map(function (item) { item.last_reply_at = util.getDateDiff(new Date(item.last_reply_at)); return item; })) }); setTimeout(function () { self.setData({ hidden: true }); }, 300); } }); ``` 这里很简单 - get请求 - url = Api.getTopics(data) - success 是当请求成功的时候的回调处理 和ajax基本一样,对比$.ajax,想想 ![Request](images/request.png) 更多示例 ``` wx.request({ url: 'test.php', data: { x: '' , y: '' }, header:{ "Content-Type":"application/json" }, success: function(res) { var data = res.data; } }); ``` 剩下的我们还需要啥呢? > 后台接口api开发就够了 ### Page的生命周期 http://wxopen.notedown.cn/framework/app-service/page.html ![Lifecycle](images/lifecycle.png) 群里有iOS工程师 ``` @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end ``` 页面刚进来的时候掉的viewDidLoad,而html里的onload,是不是非常类似?会有人想到dp里的模板模式么? ``` //index.js Page({ data: { text: "This is page data." }, onLoad: function(options) { // Do some initialize when page load. }, onReady: function() { // Do something when page ready. }, onShow: function() { // Do something when page show. }, onHide: function() { // Do something when page hide. }, onUnload: function() { // Do something when page close. }, // Event handler. viewTap: function() { this.setData({ text: 'Set some data for updating view.' }) } }) ``` ### tab 模板 ``` 全部 精华 分享 问答 招聘 ``` 事件触发 ``` catchtap="onTapTag" ``` 这个也是Page上下文里的方法 ``` onTapTag: function (e) { var self = this; var tab = e.currentTarget.id; self.setData({ tab: tab }); if (tab !== 'all') { this.fetchData({tab: tab}); } else { this.fetchData(); } }, ``` 那么如何知道e里都有啥呢? 简单的打印log即可 ![E](images/e.png) 简单的调试 ![Debug](images/debug.png) ### 上拉加载下一页 所有的组件能和object是一样,就2各种:属性(基本类型,Boolean,Number,String)和行为(EventHandle) ``` ``` 这里的class,style,scroll-y,bindscrolltolower都是属性,唯一不一样的是bindscrolltolower,它实际上是行为 ``` bindscrolltolower EventHandle 滚动到底部/右边,会触发scrolltolower事件 ``` 即我们在移动端常说的上拉加载更多。 这和我们写react、vue实际上是非常类似的。 https://github.com/airyland/vux/blob/master/src/components/panel/index.vue ``` ``` ### loading 其实非常简单的,定义模板 ``` ``` 那这个`hidden="{{hidden}}"`呢?模板都是data里的,so ``` Page({ data: { title: '话题列表', postsList: [], hidden: false, page: 1, tab: 'all' }, ``` 默认是false,因为一进来就要loading。。。 进来的时候通过lifecyle的onload ``` onLoad: function () { console.log(1) this.fetchData(); }, ``` 然后隐藏loading的操作就在http请求数据之后了。 ``` wx.request({ url: Api.getTopics(data), success: function (res) { self.setData({ postsList: self.data.postsList.concat(res.data.data.map(function (item) { item.last_reply_at = util.getDateDiff(new Date(item.last_reply_at)); return item; })) }); setTimeout(function () { self.setData({ hidden: true }); }, 300); } }); ``` 其中的 ``` self.setData({ hidden: true }); ``` 还得上文中说的data是全局上下午吗? ### 页面间跳转 模板定义 ``` ``` 注意 > catchtap="redictDetail" page里的redictDetail方法 ``` redictDetail: function (e) { console.log('我要看详情'); var id = e.currentTarget.id, url = '../detail/detail?id=' + id; wx.navigateTo({ url: url }) }, ``` 实际上有2种,上面是通过api实现的,还有一种是通过指令来实现的 ``` 跳转到新页面 在当前页打开 ``` ### utils定义 page里 ``` // posts.js var Api = require('../../utils/api.js'); var util = require('../../utils/util.js'); ``` api.js具体内容 ``` 'use strict'; var HOST_URI = 'https://cnodejs.org/api/v1'; var GET_TOPICS = '/topics'; var GET_TOPIC_BY_ID = '/topic/'; function obj2uri (obj) { return Object.keys(obj).map(function (k) { return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); }).join('&'); } module.exports = { // 获取列表数据 getTopics: function (obj) { return HOST_URI + GET_TOPICS + '?' + obj2uri(obj); }, // 获取内容页数据 getTopicByID: function (id, obj) { return HOST_URI + GET_TOPIC_BY_ID + id + '?' + obj2uri(obj); } }; ``` 感觉跟啥像? ### Promise? ![Async](images/async.png) - [微信小程序使用Promise](https://cnodejs.org/topic/57eb4e4bea2fa420446d4371) ### wxss http://wxopen.notedown.cn/framework/view/wxss.html ## 缓存 这里没有使用,如果使用登录的时候就需要了,比如token 文档 http://wxopen.notedown.cn/api/data.html k-v的,还是比较有限的 ## websocket - pub/sub - im ## canvas # 高级玩法 https://github.com/MeCKodo/wxapp-cli 优势 1.可以在任意IDE中开发 2.可使用ES6或ES5 3.支持sass和less 4.可以同时编写.html|.wxml,.wxss|.scss|.less 文件,最后都会转换为.wxml和.wxss 5.编写完任何文件(包括.json)只需要去微信开发者工具中点击重启即可预览 6.NODE_ENV 环境切换 (dev|production) 7.支持eslint (在gulpfile文件打开36行注释即可,下个版本会集成到cli配置选项中) 劣势 1.由于微信封闭的环境内,所以没有sourcemap,但这不太影响调试(即使是经过编译后的代码,本人测试了出bug的代码,还是可以从控制台跳到源码的地方) 2.由于微信封闭的环境内,无法实现reload或者hot reload PS: 当然如果你不想写ES6也是完全可以的 在后面统一介绍命令 # Q & A总结 ## 微信小程序开发需要具体哪些技术知识? - 会js、css - 理解移动端h5相关开发概念 - 使用微信提供的wxml和wxss - 熟悉微信提供api - 熟悉http协议 ## 适合0基础的前端工程师学习? 和h5类似,入门简单,精通很难 ## 微信小程序跟HTML5、Web APP的关系 - 小程序不是HTML5,也不是Web APP - 都是展示层的 - 基础知识都是一样的,移动端,http协议等 - api和开发方式有一定差异,都属于受限开发 - 小程序的抽象程度更高,与是h5实现还是native实现无关 - 和Web App关系不大,但会Web App学这个还是比较容易的 ## 怎么学习微信小程序,如果没有邀请码,可以怎么学? 上面讲过了 ## 如何看待h5? 我曾讲过,未来是h5的,原因有2 硬件越来越牛逼,廉价,内存不会成为限制条件 网络带宽越来越牛逼 这估计也是目前h5受限的2个主要点吧。 微信公众号时代,引入h5,以及手游,算是让h5火了一把,但整体来说开发体验并不好,一般大家只用h5写一些交互少、偏于展示层的东西。而完整的hybrid应用,还是要有一定比例的借助native来实现一些原生功能的。 无论是h5虚拟化也好,还是各种折腾,比如cordova,react natvie也好,我一直认为它们是过渡状态,从native到h5的过程中,限于条件妥协的产物。当然,在目前来看,想要取得好的效果,难免要使用它。 最近几年,被h5冲击的native开发越来越惨淡(相比2010年到2014年),甚至有人说app已死,开发公众号h5就可以了。这是客观的某种事实,确实微信有用户基数,是比较好的入口,另外你需要的功能基本上都可以实现。而且成本上,相对要低一些。 可,它真的很完美么? 不见得吧,1)跨平台是永远的痛,一般连iOS6+,Android 4+都很难兼顾,有时候讨厌的让人不禁想起f**k ie6.。。 2)各个浏览器,版本实现不一致,以存储为例,localstorage,sqlite,indexedb等,每个版本可能都不一定支持,又何谈通用性呢?混乱不是不能解决,成本问题,3)开发看着容易,但你很难找到好的开发人员。写的话大家差不多都可以,但谈到优化,大部分人都怂了,这其实也是目前h5效果不好的原因。 在平衡时间和实现之间,有时我们忍了。。。这大概就是未来吧 说了一堆h5的缺点,也说说它的优点吧,目前无数开拓者,前仆后继,都投入到这个坑里,无数的解决方案,框架,优化,每天都在产生。我们现在觉得前端发展无比迅速,其实很大比例是h5推动的,它已经是前端领域必不可少的组成部分。无论是vue 2, ng2,ionic2等都是比较优秀的,甚至基于weui都衍生出大把的框架。这是时代带给我们的,是挑战,也是机遇 再说说人的问题 传统的前端不会h5都不好意思说自己是前端,目前招聘最火就是前端了,面试是不可能不问h5相关问题的 iOS和Android开发,如果不会h5,未来的出路会越来越窄,当下北京的iOS培训出来的都很难找工作(甚至有不要薪水蹭经验的)。对于那些在职的人来说,每天领导都在“算计”他们,要不hybrid? h5就像前端开发里躲不开Node.js一样,无论你是做什么的,你都绕不开h5 再回头说微信应用号这事儿,微信会变成OS(操作系统),以后大家只要用我就好了,把其他应用变成微信下面的子应用,这下世界就清净了。以前一直觉得chrome os的理念很先进,不想竟然微信实现了。。。 微信下一步可能要和手机厂商合作了,手机里只有微信OS,打开就是微信界面,然后想安装应用,请打开微信OS里的h5 app store。。。 是不是挺吓人的一件事儿?估计其他大厂又要躲在厕所哭泣:不要让我的app下架。。。,微信说:你司核心价值观有问题,改了之后再说吧 ## 如何快速学习? 小程序只是增加了一种选择,以前是h5,pc,app,现在是小程序,h5,pc,app,它们无疑都是展示层的实现,所以对后台是没有影响的。它们的共性是会js能让你开发的更好,而今Node.js凭借其性能和强大npm生态,以及在大前端的火爆,使得Node.js无处不在。 > Node全栈是一个比较好的方向,如果不想全栈,你至少要考虑前端 现代web开发里的大前端 ![0](images/node/0.png) ![1](images/node/1.png) ![2](images/node/2.png) ![3](images/node/3.png) 更多的 高可用架构专用《全栈工程师之路-Node.js》 http://i5ting.github.io/nodejs-fullstack/ ## 关于小程序未来 - 开发组件定义 - html转wxml,目前已经有人做了 - 扫一扫 - schema url open # 推荐一些学习资料 参见 - https://github.com/justjavac/awesome-wechat-weapp - http://wxopen.notedown.cn/ # 关于现状 ![](images/stuq.png) - 技术发展太快,是指数型发展 - 人的学习速度是平滑的上升的曲线(学习到一定程度也是指数型上升的) - 持续学习,利用好时间,每日精进 # 作业 这个分类tab实现的太low了,很明显没有花费时间,如何通过class属性来实现一个更加好看的,带有选中状态的分类tab么? 大家可以自己试试 # 写在最后 - 玩出乐趣,想想本文是怎么玩的? - 利用好时间:闲时要有吃紧的心思,忙里要有偷闲的乐趣 - 少抱怨,多思考,未来更美好 - 每日精进,自有成为大牛之日