- 【转】用nodejs快速实现微信小程序的websocket服务端
摘要: 微信小程序服务端使用websocket方式。socket.io已作为nodejs体系中被广泛应用的websocket解决方案,却因socket.io对websocket做了高级封装,不能兼容微信小程序所采用的websocket标准协议无法直接使用,此外微信小程序还要求websocket必须是ssl的。本文着重介绍如何ws库和ssl证书实现微信小程序的websocket服务端。 微信小程序对第三方服务端的网络通信方式支持https和Websocket。WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。为了解决HTTP协议效率低下的问题,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。WebSocket在数据传输的稳定性和数据传输量的大小方面,具有很大的性能优势。有不少公司将nodejs的socket.io作为websocket的解决方案,很遗憾的是socket.io是对websocket的封装,并不支持html5原始的websocket协议,微信小程序使用的websocket却是接近于html5原始websocket协议,socket.io居然没有用武之地了。当然情况也没有惨到需要你自己一步一步去实现websocket服务端,我们的大node有很多websocket库,ws就是其中一个,号称最轻量级,最快。ws的用法比较简单,直接看github说明(https://github.com/websockets/ws)就可以。我这里着重讲的是针对微信小程序实现的加入ssl的websocket实现。 要使用ssl,首先你得有ssl证书,生产环境建议你去买一个ssl证书。开发环境你可以给自己生成一个ssl自签名证书临时用一下。 这里说下Linux 系统怎么通过openssl命令生成 证书。 首先执行如下命令生成一个key [代码]openssl genrsa -des3 -out ssl.key 1024[代码]然后他会要求你输入这个key文件的密码。不推荐输入。由于生成时候必须输入密码。你可以输入后 再删掉。 [代码]mv ssl.key xxx.keyopenssl rsa -in xxx.key -out ssl.keyrm xxx.key[代码]然后根据这个key文件生成证书请求文件 [代码]openssl req -new -key ssl.key -out ssl.csr[代码]以上命令生成时候要填很多东西 一个个看着写吧(可以随便,毕竟这是自己生成的证书) 最后根据这2个文件生成crt证书文件 [代码]openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt[代码]这里365是证书有效期 。这个随意。最后使用到的文件是key和crt文件。 nodejs websocket(ssl)服务端实现,wss-sample.js [代码]'use strict';var fs = require('fs');// you'll probably load configuration from configvar cfg = { ssl: true, port: 8080, ssl_key: 'ssl.key', ssl_cert: 'ssl.crt'};var httpServ = (cfg.ssl) ? require('https') : require('http');var WebSocketServer = require('ws').Server;var app = null;// dummy request processingvar processRequest = function(req, res) { res.writeHead(200); res.end('All glory to WebSockets!\n'); };if (cfg.ssl) { app = httpServ.createServer({ // providing server with SSL key/cert key: fs.readFileSync(cfg.ssl_key), cert: fs.readFileSync(cfg.ssl_cert) }, processRequest).listen(cfg.port); } else { app = httpServ.createServer(processRequest).listen(cfg.port); }// passing or reference to web server so WS would knew port and SSL capabilitiesvar wss = new WebSocketServer({ server: app }); wss.on('connection', function(wsConnect) { wsConnect.on('message', function(message) { console.log(message); wsConnect.send('reply'); }); });[代码]运行这个案例, 你需要先安装ws库。 [代码]npm install ws[代码]运行: [代码]node wss-sample.js[代码]你可以在浏览器打开https://localhost:8080,在浏览器控制台验证一下websocket是否可以连接: [代码]var socket = new WebSocket('wss://localhost:8080/'); socket.onmessage = function (e) { console.log('Server: ' + e.data); }; socket.send('your message');[代码] 如果是在express框架下实现websocket(ssl)。wss-express.js: [代码]'use strict'var fs = require('fs');var https = require('https');var server = https.createServer( { 'key':fs.readFileSync('ssl.key'), 'cert':fs.readFileSync('ssl.crt') } );var url = require('url');var WebSocketServer = require('ws').Server;var wss = new WebSocketServer({ server: server });var express = require('express');var app = express();var port = 8080; app.use(function(req, res) { res.send({ msg: "hello" }); }); wss.on('connection', function connection(ws) { var location = url.parse(ws.upgradeReq.url, true); // you might use location.query.access_token to authenticate or share sessions // or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312) ws.on('message', function incoming(message) { console.log('received: %s', message); }); ws.send('something'); }); server.on('request', app); server.listen(port, function() { console.log('Listening on ' + server.address().port) });[代码] 简单的微信小程序websocket服务端实现了。 原作者:小水熊
2016-11-23 - 【转】微信小程序中使用微信风格样式库-WeUI
WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。包含button、cell、dialog、 progress、 toast、article、actionsheet、icon等各式元素。 [图片] WeUI WeUI的官方演示地址是:https://weui.io/ WeUI的官方GitHub地址是:https://github.com/weui WeUI最初是为HTML5的页面设计的样式库,现在微信小程序使用的样式机制也是css风格的样式机制(不过稍稍有些不一样的地方),WeUI理所当然的推出了WXSS版本。它的GitHub地址是:https://github.com/weui/weui-wxss 我们可以直接去Github上下载它的代码,也可以通过npm来方便的获取: [代码]npm install weui-wxss[代码]下载下来的代码中,包含了weui的源代码,以及一个基于weui的示例小程序: [图片] 示例小程序 里面包含了丰富的使用weui的示例代码,可以很好的学习weui提供的各个样式的使用。 我们可以通过微信web开发者工具来打开这个示例代码: [图片] 示例代码 [图片] button样式 你的小程序主要是通过在你的app.wxss中导入weui.wxss来导入WeUI的样式的: [代码]@import "style/weui.wxss";[代码]之后,就可以在小程序的各个地方使用WeUI中定义的样式了。 作者:一斤代码(简书作者) 来自:http://www.jianshu.com/p/f4e3212c9ca7
2016-11-22 - 【转】微信小程序weapp的底层实现原理
首先声明: 以下所有内容仅是对微信小程序weapp的个人研究,仅有参考价值,不确保正确; 以下所有内容仅用于交流学习,不能做其他用途,欢迎大咖指点 其他 以下简称wa(weapp, 微信小程序) 一. wa的运行环境 根据微信官方的说明,wa的运行环境有3个平台,IOS的webkit(苹果开源的浏览器内核),Android的X5(QQ浏览器内核),开发时用的nw.js(C++实现的web转桌面应用); 二. 为什么wa不直接运行在浏览器(webview)中,而要绕过浏览器直接调用内核呢? 因为运行在浏览器中的webapp是做不了监控的,而wa的表现是半native app,半web app,而native app与web app和一个很重要的区别就是native app有自己的生命周期,在这之中,我们可以根据生命周期的不同时间段做出不同的调整,比如常驻内存,防止被系统杀掉,系统后台保存活度等等,而web app就没有这回事了,仅仅能够根据事件做出不同的调整,跟原生app比起来,体验就差了一些。基于此,wa当然不会像web app一样了,他需要有自己的生命周期。 本质上来说,wa还是运行在浏览器模式中,而承载wa的系统就是微信,用微信来管理wa的生命周期。而微信,现在本身就是一个系统。 微信官方贴出来的生命周期函数主要有以下3个:onLaunch(初始化完成),onShow(启动时,后由后台进入前台),onHide(由前台进入后台) 三. wa的本质是什么 wa的本质就是富单页面web应用。首先,一个wa应用程序就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但与传统的webapp不同的是,它也可以做得很丰富,就像native app一样,可以调用原生的各种接口,像网络状态、罗盘,重力,拨打电话 四. wa的wxml, wxss与html, css之间的关系 理解了wa的本质,基本上就应该比较清楚的wxml, wxss与html, css之间的关系了。很明显,wxml就是wa的模板语言,在正式部署的时候,会转化成HTML语言,而wxss则会转化为css; 那他们又是怎么转化的呢?wxml转化为html用的是 https://github.com/facebook/react,包括里面整套的逻辑都是建构在reactjs之上的;而wxss与css基本上没有任何不同,除了wa使用的长度单位是rpx之外。 加个题外话:微信官方定义的手机整个宽度是750rpx,但我觉得定位375rpx似乎更为恰当(理由与本主题无关,略)。 五. 小程序的生命周期与调用系统的api是如何实现的 这个就得依赖WeixinJSBridge.js这个脚本了,所有的关键都在这个脚本上。wa通过这个脚本调用原生的接口,而微信用这个脚本来管理wa,包括它的生命周期。这里只谈原理就不贴代码了。Android可以参考 https://github.com/lzyzsd/JsBridge,IOS可以参考 https://github.com/marcuswestin/WebViewJavascriptBridge 六. 传统的js库能用吗 大部分都不行。官方的解释是 [代码]页面的脚本逻辑是在JsCore中运行,JsCore是一个没有窗口对象的环境[代码]所以不能使用bom相关的对象。而依赖bom的常用的比如说jQuery就无能为力了。这种说法太牵强了。实际上,这是故意为之的。wa正式部署使用webpack打的包,而在打包的过程中,把以下变量给屏蔽了: [代码]window,document,frames,self,location,navigator,localStorage,history,Caches,screen,alert,confirm,prompt,XMLHttpRequest,WebSocket[代码]自然你就访问不了bom对象啦,当然其他很多对象也不能访问啦。这些对象如果访问,就是undefined。 为什么要这样做呢?还不是为了管理和监控嘛。如果这些对象你能访问,那么你就可以像操作通常的网页一样操作wa,这是绝对不被允许的,所以,你懂的。 具体是怎么屏蔽的,帖段代码: [代码]define("...", function(require, module, exports, window,document,frames,self,location,navigator,localStorage,history,Caches,screen,alert,confirm,prompt,XMLHttpRequest,WebSocket ){});[代码]七. 在native app中是如果实现多个应用的多个生命周期的 我的想法是微信在内部维持了一个栈,用来装载wa,而且会记录一些信息,方便管理。但这个栈比较特别,没有先后顺序,仅仅是坐个排排而已。至于这个栈是在native中实现还是在web中实现,目前还不得而知。 原作者: senntyou
2016-11-22 - 【转】一篇文章读懂微信小程序(应用号)是什么?
[图片] 距离张小龙的那场首次公开演讲已经有九个月了,而在那场演讲中备受关注的「应用号」在千呼万唤中终于以「小程序」的名字正式对外小范围公测,不少创业者表示机会来了跃跃欲试。诚然,微信每次放出的大招,不管是公众号、服务号、朋友圈广告等,对于抢先抓住机会的人都是不小的红利。而这次这个大招,或许足以影响现有移动互联网的格局。 张小龙在朋友圈里这样解释道:小程序是一种不需要下载安装即可使用的应用,它实现了应用「触手可及」的梦想,用户扫一扫或搜一下即可打开应用。也体现了「用完即走」的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载。 对于希望从「小程序」中获取红利的创业者,不妨好好读完这篇文章。做不做?比怎么做更重要! 一、「小程序」和「公众号菜单栏内嵌H5」有什么区别? [图片] 看上图展示的小程序截图,像不像一个Native APP加了一个顶部微信菜单的帽子? Native APP和Web APP谁是未来的主流这个命题争了很多年,而Native APP最大的优势也就是对于系统控件接口和框架的调用能力比Web APP不知道高到哪里去。虽然京东同时提供了手机APP和手机H5形式的页面供用户浏览和下单,但是同时用过二者的都能体会到,H5页面在流畅度上还是差一些。 在此之前,很多创业者以公众号菜单栏内嵌H5的形式,完成了基础功能的微信化植入,但通常都是比较简单的页面,操作体验比较一般。 这次微信推出的小程序,最大的亮点在于微信提供了丰富的框架组件和API接口供开发者调用,具体包含:界面、视图、内容、按钮、导航、多媒体、位置、数据、网络、重力感应等。在这些组件和接口的帮助下,建立在微信上的小程序在运行能力和流畅度上面便可以保持和Native APP一样的体验。 二、当我们谈创业的时候,我们到底在做什么?过去两年在资本的推动和互联网+概念的热炒之下,出现了罕见的创业热潮,各种各样的创业项目出现,应用市场内APP的数量也井喷式增长。 行业里有一个很大的误区:互联网创业=做个网站;移动互联网创业=做个APP。 很显著的现象就是很多传统企业在还没搞清什么是互联网+的时候,就迫不及待地做APP了,做出来了有没有人用,当然那是另外一回事。 回到创业这件事上,还是得回归商业的本质,商业是提供顾客所需要的物品和服务的一种行为。所以不管是网站,还是APP,或者很多创业者已经在尝试的微信公众号,甚至是QQ群、微信群,这都是连接用户的一种载体。传统商业依赖于线下实体门店为顾客提供服务,互联网的存在将获取新客户和提供服务的场景进行了线上化改造,从而提升了商业效率。 最近有一家花店在我的同事间很受欢迎,它会给顾客每周固定时间会送来一束搭配好的花。这是一个没有实体店的花店,也没有APP,唯一的载体就是微信公众号,下单支付是在微信号内,信息填写修改是在微信号内,客服也是在微信号内,好像除此之外也没有更多其他需要的功能了。所以这样一个创业项目,微信号就足以满足其大部分的需求,虽然在某些环节上可能有些体验粗糙,但相比之下单独做个APP?哪边成本更高呢。 三、为什么微信小程序的诞生对创业者是好机会1.APP流量成本的急剧攀升 做渠道运营的同学可能会清楚,过去两年里,APP推广的成本是呈翻倍增长的。有些垂类APP的CPA单价高达500元以上,对于创业者来说没有太多钱可以去砸在流量上,但流量往往是控制产品生死的命脉,每年有50%的新APP死在流量问题上。 2.移动互联网格局基本已定,用户主要需求场景已被巨头把持 移动互联网发展已有五年时间,在这几年时间里,从PC时代迁移过来的连接人与信息、连接人与人、连接人与商品、连接人与服务四个大类已经基本完成了格局重塑。用户的主要需求场景,尤其是同时具备刚需和高频两个特点的场景,基础工具、生活服务、娱乐等都已经有PC时代的老巨头继续把持,或者移动互联网新生的小巨头们占据山头。 3.面向所有产品对用户时间的竞争 在之前的文章里,白崎反复讲过一个观点就是现在的竞争不仅仅是同类竞品的竞争,其实是你在和所有产品竞争用户的时间。显然微信是目前的翘楚,平均每天长达4小时以上的停留时长。很多APP面临的问题便是用户即便下载安装了,但也想不起打开,或者打开了很快就被关闭。 在以上三个背景的情况下,对创业者而言环境真的很糟糕,用户获取难、使用率不高是普遍的痛点。在年初的「应用号」概念发布时,便赢得很多创业者的期待,原因就在于大家希望从微信这棵大树上获取一些红利。 四、移动互联网第二春:SuperAPP+LightAPP模式轻应用是一种趋势,早在2013年左右,百度和UC分别对「轻应用」的模式进行了尝试,虽然都失败了,但不可否认这条路的正确性,只是在当时这两家都不具备发展起生态的能力。 百度的轻应用是以搜索为核心的生态,UC的轻应用是以浏览器为核心的生态,二者都是Web APP的插件化思路。百度轻应用接入了如「顺丰快递」为代表案例的信息查询服务入口,UC轻应用则接入了「迅雷」「快播」为代表案例的和浏览器场景强结合的信息查询、信息下载的入口。 复盘为什么百度和UC都没做起来,一个重要的前提是当时的百度和UC都不具备SuperAPP的根基,尤其是不够高频,所以带不起来这个生态。 但2016年的微信来做这件事,天时地利人和似乎都占据了,既有海量的用户,强大的用户粘性,足够长的用户使用时长,是国内目前最称得上SuperAPP的应用了。 白崎预估,这种SuperAPP+LightAPP的模式或许能够带起移动互联网的第二春,很多长尾的需求之前由于落地条件不成熟不能做的,现在可以重新回来尝试一下。即使是很小的一个需求点,以LightAPP的形式附着在微信上,现在也具备了一定的生存空间。 五、谁适合抓住这波红利在别人家平台玩,首先得研究平台欢迎什么样的人。从微信官方对外公布的信息来看,最鼓励的是服务提供者,因为这和微信「连接人与服务」的战略诉求最为契合。 白崎的建议是:低频、非刚需场景的长尾服务提供者最适合来做微信小程序。 高频场景的服务依然适合以独立APP作为阵地,即便微信在发现Tab内给京东开辟了最明显的「购物」二级入口,依然是用手机京东APP的人多,即使在体验上大大增强的微信小程序推出后,结论依然会是如此。 高频场景的服务天然具备独立发展成生态的潜力,可以自成一套生态体系,比如服务领域的滴滴出行。即使是在微信、支付宝、微博中都开辟了打车入口,这些也只是增量,自家APP还是主要的阵地。 而对于低频、非刚需场景的长尾服务而言,由于需求通常较为简单,使用频次低,撑不起来一个独立APP,寄生在巨头身上是最好的选择。 正如把支付宝中的「转账」、「付款」、「信用卡还款」、「生活缴费」等拆成一个个独立APP,用户肯定不会买账,但把所有跟钱相关的需求都汇聚在一起,哪怕是非常长尾的水电燃气物业费和ETC交费通通都涵盖,这才成就了今天的国民应用支付宝。 现在,微信正在试图开放接受长尾的需求场景,把自己打造成一个无所不包的生态系统。这个系统,包含人与人的连接,包含人与信息的连接,包含人与商品的连接,更包含各类大大小小的服务连接。 比如上面提到过的花店的案例,符合低频场景、长尾服务的特点,他们家就非常适合做微信小程序,而且只要在现有基础上把微信内嵌H5迁移成小程序,就能改善下单流程、客服等方面的体验优化,从而更好地维系用户。 六、决定开发微信小程序之前,这三个担忧不容忽视听到「小程序」发布的消息后,相信很多人都跃跃欲试,觉得得抓住机会。其实风险与收益共存,下面这三个担忧在决定做之前,得想清楚。 1.如何区分现有独立APP和微信小程序的定位对于还没有开始做APP的创业者,小程序的发布恰似一阵甘霖,来得正是时候。但对于已经开发了独立APP的创业者呢?开发一个一模一样的微信小程序出来,是否会出现零和博弈造成原有独立APP的荒废? 白崎的建议是,维持原有独立APP的持续迭代更新,把微信小程序作为新的增量部分,在用户数据上做到两边的一致性。把选择权交还给用户,用户总是会选择更适合自己的那一边。是否弃掉独立APP,得用数据来说话。 还有一种方式,可以将微信小程序作为一个lite版,进行产品功能的MVP试验。 至于以哪边作为主要用户阵地,还得结合用户获取成本来看。在同时满足业务需要的情况下,如果花最少的成本,能获取更多的用户,有什么理由说不呢? 2.假如微信封了你的小程序,怎么办?微信在过去几年里有一个很大的特点就是生态封闭,这和苹果有些相似。很多创业者借助社交红利尝到甜头,也有因违反规定被微信做封号处理,一夜之间回到解放前。 以下案例想必还历历在目: 诱导关注、诱导分享:封号 淘宝链接:屏蔽 虾米音乐分享链接:屏蔽 在朋友圈里传播外链达到一定次数:屏蔽,严重封链接 在微信生态里玩,永远要忌惮红线在哪儿,毕竟微信具备随时掐断脖子的能力,只是它愿不愿意动手的问题。所以做之前熟悉规则很重要,当然也有时候只是简单的立场站队问题。 3.同样存在用户获取成本变高的问题 现在获取用户难是因为手机里的APP太多,应用分发的入口变得集中从而用户获取成本价格昂贵,流量问题从移动互联网诞生至今都是创业者最大的困扰之一。 等红利期过后,微信小程序是否也会出现这个问题呢? ①如何获取用户关注 虽然微信小程序不需要下载安装,但是在成千上万的小程序中,用户从哪儿知道你,找到你呢。对此张小龙的朋友圈里提到了「扫一扫」和「搜一下」这两种方式。 不管是关注还是扫一扫,首先得让小程序能够触及到用户,才有被用户使用的可能,正如APP首先得被下载安装才能使用。 搜索,是一个基于品牌的行为。搜索精准的产品关键词,首先得让用户知道你的品牌才有可能搜索到,这对初创品牌是硬伤。搜索行业关键词或泛需求类的关键词,如何在最明显的位置出现在用户面前且引导用户点击前往,OMG,难道也要竞价吗? 这些都是可以预见到的用户获取成本问题。 ②如何在臃肿的微信中获得存在感,实现用户留存和用户维系 不得不说微信现在已经开始臃肿了,刚看了下手机,微信占据了9.8G的内存容量(前不久才刚清理过一次),过去24%小时微信耗去43%的手机电量,另外据微信官方公布数据,用户平均在微信的停留时间为4小时。这背后是好友对话聊天、群消息、订阅号、服务号、朋友圈等一系列微信自有功能所带来的信息堆积。 等全面开放公测之后,随着开发者的增多,微信自有功能、第三方小程序功能混合在一个容器里,获得存在感可不是一件简单的事情。如何在微信里做好用户留存和用户维系,也是一个难点。 新机会出现时,选择做不做比怎么做其实更重要。 作者:白崎(简书签约作者) 原文链接:http://www.jianshu.com/p/a256ea4a3d0e
2016-11-21 - 【转】微信小程序的缓存策略分析
文件缓存特性: 1.由于小程序的缓存没有时效性 2.文件缓存大小限制 3.需要针对特定业务群进行缓存更新 4.一键清空缓存 5.针对不同用户,对应的缓存是公共的,没有隔离。因此缓存针对不同的用户,使用该用户特定的key来隔离。 那么对应的解决方案是什么呢 解决方案: 1.缓存前缀,带上用户标识_缓存名 2.每个缓存,需要记录缓存大小、缓存名、缓存类名、缓存生成时间、缓存失效时间到一个公共的缓存类中。 3.有一个设置缓存,如果目前系统缓存大小,启动失效缓存清理机制方法。 4.当手机网络非常好的情况下,基本上走线上实时数据策略 当网络不好,尽量走本地缓存策略。 5.为了更好地提高用户体验度,有一个提前加载数据的策略。例如打开首页后2秒,自动加载请求未来用户需要请求的数据,入缓存数据。 [图片] 初步分析的,希望对大家有用 缓存策略的好坏,影响到小程序加载的效率和用户体验度 缓存,可以在客户端后台,进行静默加载常用的,这样用户在进入第二页,将会加快打开。提高用户体验度。 原作者: guoyan2008 来自: http://www.henkuai.com/thread-16292-1-1.html
2016-11-21 - 【转】代码构建初探:如何继续使用html与css开发小程序
原文来自掘金,已获授权,地址为授权地址 以下为部分本文有用评论: @1棵拼搏的寂静草 vscode 自带修改文件的语言,files.associations,直接 wxml 指向 html,wxss 指向 css 就好了。 @linshuai webstorm 设置一下 html 关联. wxml 格式文件,一样可以像 html 一样使用 emmet 正文: 微信小程序似乎会给互联网带来一场非比寻常的变革。随处可见关于小程序的文章也让我们感受到它正在刮起一阵风暴,所以呢,抽空研究研究它,还是非常有必要的,加上最近小程序公测,通过注册未认证的小程序,我们可以得到一个appid,下载最新的开发工具,就可以开始尝试编写一些demo了。 但是在开发小程序的时候,由于我们比较常用的编辑器对于[代码].wxml, .wxss[代码]后缀的文件并没有多少支持,目前我所知道的,除了vs code有一个叫做vs wxml的插件之外,几乎没有其他插件了,因此,没有代码补全,没有emmet支持,没有代码高亮,这极大的影响了开发效率,我也知道有很多来尝试小程序开发的同学为此而非常困扰。 好在,办法总是有的。 大家都知道大多数编辑器对于html与css的支持非常全面完善,特别是emmet插件,对于html和css来说,已经变得必不可少了。而微信的wxml与wxss其实与html与css差别并不大。因此,我们只需要在开发时,将代码写在html与css中,在保存时,通过构建工具,将文件的后缀名改成.wxml与.wxss即可。这样一来,我们就不用在内置工具中开发,不用到处找对于小程序支持良好的IDE,也不用等各位大佬出新的插件了,就用我们各自最喜欢最熟悉的编辑器就可以。下面我以我最熟悉的gulp为例,与大家分享一下具体如何实现。 准备我们知道小程序的页面都在pages文件夹下,首先创建一个demo文件夹,这里将会放置我们的新页面,并在demo文件夹里创建一个dev文件夹,用于存放html与css文件,大概的目录结构如下 [代码]// + 表示文件夹 - 表示文件+ pages + demo + dev + html - demo.html - demo2.html + styles - demo.scss - _reset.scss - _libs.scss + scripts - demo.js[代码]因为在平时开发中,常常将scss编译为css使用,因此这里我们也用scss来进行开发 编译之后,得到的结构大约如下 [代码]+ pages + demo + dev - demo.wxml - demo.wxss - demo.js - gulpfile.js[代码]我们的目的,就是将dev中的html,js,scss,通过gulp,编译成为小程序能够支持的wxml,js与wxss,在清楚了目的之后,我们就来添加gulp任务就行了。 首先在gulpfile.js中定义一个路径对象,以方便后续的使用 [代码]// 设置相关路径var paths = { wxml: 'html', wxss: 'styles', js: 'scripts', img: 'images'};[代码]具体要使用那些gulp插件,大家在使用的时候根据提示安装即可,因为是根据之前的老文件修改,比较懒没有去区分具体使用了那些插件,见谅。 HTML对于html的处理比较简单,只有2个操作,修改后缀名与在你希望的位置生成新的wxml文件 [代码]gulp.task('wxml', function() { var src = [paths.wxml + '/**/*.html']; return gulp.src(src) .pipe(plumber({ errorHandler: handleError })) .pipe(foreach(function(stream, file) { return stream.pipe(rename(file.relative.replace(/.html/gi, '.wxml'))); })) .pipe(gulp.dest('../')) .pipe(notify({ onLast: true, message: "transform wxml success!" })); });[代码]JSjs就更简单了,由于开发工具自己内置了编译方式,我们只需要按照commonJs的方式处理自己的代码就行,不需要进行额外的处理,但是为了统一,也将开发代码放在dev文件中,编译时在你想要的位置重新生成即可 [代码]gulp.task('wxjs', function() { var src = [paths.js + '/**/*.js']; return gulp.src(src) .pipe(plumber({ errorHandler: handleError })) .pipe(gulp.dest('../')) .pipe(notify({ onLast: true, message: "transform wxjs success!" })) });[代码]SCSS对于scss的处理工作稍微要多一点,我们的主要目的是要继续使用scss的语法与特性,并最终编译成.wxss文件 [代码]gulp.task('wxss', function() { var src = [paths.wxss + '/**/*!(_).scss']; return gulp.src(src) .pipe(plumber({ errorHandler: handleError })) .pipe(foreach(function(stream, file) { return stream .pipe(path.extname(file.relative) == '.less' ? less() : sass().on('error', sass.logError)); })) .pipe(csscomb()) .pipe(minifycss({ aggressiveMerging: false, advanced: false, compatibility: 'ie7', keepBreaks: true })) .pipe(cssbeautify({ autosemicolon: true })) .pipe(foreach(function(stream, file) { return stream.pipe(rename(file.relative.replace(/.css/gi, '.wxss'))); })) .pipe(gulp.dest('../')) .pipe(notify({ onLast: true, message: "browser reload for css" })); });[代码]ok,这样就大功告成了,熟悉gulp的同学可以动手尝试一下了,熟悉其他构建工具的同学也可以根据我提供的思路实现同样的效果。想来也是不难的。当然,这只是代码构建的一些小的尝试,当面临具体项目时,还需要更多更严谨的考虑才行。 完整代码[代码]'use strict';var rf = require("fs");var path = require("path");var through = require("through2");var gulp = require('gulp');var concat = require('gulp-concat');var uglify = require('gulp-uglify');var del = require('del');var gutil = require('gulp-util');var less = require('gulp-less');var minifycss = require('gulp-minify-css');var autoprefixer = require('gulp-autoprefixer');var csscomb = require('gulp-csscomb');var cssbeautify = require('gulp-cssbeautify');var rename = require('gulp-rename');var changed = require('gulp-changed');var header = require('gulp-header');var footer = require('gulp-footer');var livereload = require('gulp-livereload');var watch = require('gulp-watch');var imgcache = require('gulp-imgcache');var notify = require("gulp-notify");var foreach = require("gulp-foreach");var sass = require("gulp-sass");var sort = require('gulp-sort');var replace = require('gulp-replace');// 图像处理var imagemin = require('gulp-imagemin');var pngquant = require('imagemin-pngquant');var spritesmith = require('gulp.spritesmith');//错误捕获var plumber = require('gulp-plumber');// 设置相关路径var paths = { wxml: 'html', wxss: 'styles', js: 'scripts', img: 'images'}; gulp.task('wxml', function() { var src = [paths.wxml + '/**/*.html']; return gulp.src(src) .pipe(plumber({ errorHandler: handleError })) .pipe(foreach(function(stream, file) { return stream.pipe(rename(file.relative.replace(/.html/gi, '.wxml'))); })) .pipe(gulp.dest('../')) .pipe(notify({ onLast: true, message: "transform wxml success!" })); }); gulp.task('wxjs', function() { var src = [paths.js + '/**/*.js']; return gulp.src(src) .pipe(plumber({ errorHandler: handleError })) .pipe(gulp.dest('../')) .pipe(notify({ onLast: true, message: "transform wxjs success!" })) }); gulp.task('wxss', function() { var src = [paths.wxss + '/**/*!(_).scss']; return gulp.src(src) .pipe(plumber({ errorHandler: handleError })) .pipe(foreach(function(stream, file) { return stream .pipe(path.extname(file.relative) == '.less' ? less() : sass().on('error', sass.logError)); })) .pipe(csscomb()) .pipe(minifycss({ aggressiveMerging: false, advanced: false, compatibility: 'ie7', keepBreaks: true })) .pipe(cssbeautify({ autosemicolon: true })) .pipe(foreach(function(stream, file) { return stream.pipe(rename(file.relative.replace(/.css/gi, '.wxss'))); })) .pipe(gulp.dest('../')) .pipe(notify({ onLast: true, message: "browser reload for css" })); }); gulp.task('watch', function() { //监听文件改变触发相应任务 gulp.watch([paths.wxml + '/**/*.html'], ['wxml']); gulp.watch([paths.js + '/**/*.js'], ['wxjs']); gulp.watch([paths.wxss + '/**/*.scss'], ['wxss']); }); gulp.task('default', ['watch']);function handleError(err) { gutil.beep(); gutil.log(err.toString()); notify.onError("Error: <%= error.message %>")(err); this.emit('end'); }[代码]代码会有冗余的部分没有仔细删除,忽略即可。使用时需要根据提示安装必要的插件 关于微信小程序,如果基础不错的同学,可以去积极尝试一下的,感觉官方文档写的很清晰,模块化经验比较丰富的应该会很容易上手。对于基础比较薄弱的同学保持关注也是非常必要的,抓紧时间掌握基础才是关键啊。 原作者: 遇见波同学 来自: http://gold.xitu.io/post/581f0028a0bb9f0058b4c029
2016-11-18 - 【转】微信小程序的样式机制
之前,我已经介绍过在小程序开发中使用WXML来做界面布局,但是WXML只是一个界面的骨架。要让我们的小程序变得精致漂亮高大上起来,就需要一种为其添加样式的机制。小程序的开发框架采用了与Web开发中所使用的CSS(层叠样式表)几乎相同的一种机制,称作WXSS。 WXSS用于描述WXML的组件样式,用于决定WXML的组件应该如何显示。为了适应广大的前端开发者,它被设计为支持CSS中大部分的特性(但是注意是大部分,还是有一些特性是不支持的),并且有一些自己的扩展和修改。比如引入了一种新的尺寸单位rpx,还有@import这种外联样式的导入机制(话说这个功能不是CSS里也有的么...) 关于CSS,我就不在这里介绍它的用法了,这个内容实在有点多,还没学习过CSS的朋友可以自己找一下资料学习,我在这里主要想讲解一下WXSS和CSS之间的不同之处。 样式的设置在WXML文件中,我们可以通过style和class属性为组件设置样式。不过由于WXML的数据绑定功能的存在,我们就可以动态的设置style和class的属性值了。比如: [代码]<view style="color:{{color}};padding:{{padding}};">Hello</view>[代码][代码]<view class="message-{{type}}">{{message}}</view>[代码]不过,我们要尽量避免使用style来设置组件的样式,最好将样式定义成样式规则放到样式文件中(.wxss),然后通过class属性来设置。因为组件通过style接收动态样式,在运行时会进行解析,影响渲染性能。 有限的选择器和CSS不一样,小程序的WXSS支持的选择器的类型有限,官方文档中明确列出说支持的,目前只有以下几种选择器: .class:类选择器,例如.error-msg,它会选择所有class="error-msg"的组件 #id:ID选择器,例如#my-container,它会选择id="my-container"的组件 element:元素选择器,例如view,它会选择所有view组件 element, element:多选择器,例如view, button,它会选择所有view和button组件 ::after:例如view::after,它会在view组件后面插入内容 ::before:例如view::after,它会在view组件前面插入内容 其实自己试了一些在CSS中可用,小程序官方没有声明在WXSS里支持的选择器,也是可以生效的。但是有些用了就会把微信web开发者工具给整崩溃掉,所以,还是不要在实际开发中使用这类没说支持的选择器了,虽然在有的场景下麻烦了点,但是以上支持了的选择器还是基本够用了。 全局样式与局部样式WXSS中有全局样式与局部样式之分。 定义在app.wxss文件中的样式为全局样式,将会对每一个页面起作用。 而定义为page同名的wxss文件,则称为局部样式,只会针对对应的页面起作用,而且样式优先级比全局样式要高,可以覆盖全局样式。 新的尺寸单位最后来说一下WXSS中新增和扩展的尺寸单位,对于做屏幕的自适应是非常有帮助的。 rpx (responsive pixel,响应式px),简单来说,就是不管什么尺寸的设备,总是认为屏幕宽度是750rpx rem (root em,根em),也很简单,就是不管什么尺寸的设备,总是认为屏幕的宽度是20rem。 所以rpx和rem之间的换算,就是: [代码]1rem = (750/20)rpx = 37.5rpx[代码]设计师的设计稿一般都是按照px来做单位的,那么在开发阶段,开发人员就需要在px和rpx之间进行换算,具体可以如下来计算: [代码]rpx = (屏幕实际宽度/750)px px = (750/屏幕实际宽度)rpx[代码]因此,如果设计师的设计是以iphone6屏幕尺寸为参照(iphone6的屏幕宽度为375px),则: [代码]1rpx = (375/750)px = 0.5px 1px = (750/375)rpx = 2rpx[代码]是不是很容易理解? 好了,关于微信小程序样式WXSS的关键点内容,就讲解到这里,不对的地方欢迎指正。谢谢啦。 文/一斤代码(简书作者) 原文链接:http://www.jianshu.com/p/30caa82e55c6
2016-11-18 - 【转】TITF:tabBar的使用小技巧
本文来自公众号:TITF 一:tabBar的使用小技巧 [图片] 原理:在app.json中配置tabBar属性 3、关键代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"tabBar": { "color":"#666666", "selectedColor":"#06bd04", "list": [{ "pagePath": "index", "text": "首页", "iconPath": "images/index.png", "selectedIconPath": "images/indexHL.png" },{ "pagePath": "picDisplay", "text": "图片展示", "iconPath": "images/picDisplay.png", "selectedIconPath": "images/picDisplayHL.png" }] } 来自CODE的代码片snippet_file_0.txt 4、操作方法 新建一个项目,打开app.json文件,将关键代码复制到"window":{},后面,注意window的大括号前加逗号,如下图 [图片] 配置tabBar属性值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 "tabBar": { //设置tabBar文字默认颜色 "color":"#666666", //设置tabBar文字被选中是的颜色 "selectedColor":"#06bd04", //tab列表,数组类型,改数组内至少要有两个但不大于5个的tab对象 "list": [{ //设置tab跳转页面链接 "pagePath": "index", //设置tab上的文字 "text": "首页", //设置tab上的默认图标 "iconPath": "images/index.png", //设置tab被选中时的图标 "selectedIconPath": "images/indexHL.png" },{ "pagePath": "picDisplay", "text": "图片展示", "iconPath": "images/picDisplay.png", "selectedIconPath": "images/picDisplayHL.png" }] } 二:数据绑定一个对象到数组中,然后取值的一个注意点(分享者:guonei001)通过wx.request获取到服务器数据之后将数据(一个json对象)绑定至post数组,然后页面中获取数据的时候可以直接通过(数组名.属性)直接取值。数组中有多个json对象的话,则需要wx:for遍历取值。 单个json对象数据绑定 [图片] 页面取值: [图片]
2016-11-17 - 【转】设计微信小程序:遵循的五个原则,让你少走弯路的“潜规则” ...
要理清如何设计微信小程序,首先来弄清楚微信的意图。之前张小龙曾公开过对微信应用号的一些看法,再联系到他总结的微信产品观,大概可以总结出如下重点: 1、服务用户,不打扰用户,用完即走微信的一个基本价值观,我们认为一个好的产品是一个用完即走的。一个好的产品不是黏住用户,而是尽量让这个用户离开你的产品。希望用户在用微信的时候,最高效率把必须要做的在微信里面做完,把时间留出来去做很多别的事情。基于微信来做一些项目的时候不妨也多从这个角度思考一下,你做的事情是在帮助用户节约他的时间,提高他的效率。小程序的设计规范里,不允许推送、不允许转发至朋友圈、不允许诱导关注,一而再地强调服务导向,用户主动寻找服务,用完即走。 2、服务号未实现目标,小程序予以补充和提升并不太具备存在感的服务号,显然并没有实现微信对它的期望。服务号上线之初,也是希望可以在消息列表中为用户提供更多样化的服务,同时也提供给那些低频工具或商户,一个连接用户提供服务的可能,免除独立开发APP的成本。然而受入口位置、推送频次、交互展示、功能等限制,大部分服务号只不过是企业多了一个消息推送号,并没有拓展出新的领域。 3、刺激微信生态微信已经不年轻了。想想微信这几年的发展,曾几何时,摇一摇、群对话、朋友圈、抢红包,几乎包围了我们的生活。然而现在,有多少人关闭了朋友圈提醒?有多少人对所有微信群设置了消息免打扰?又有多少人,在朋友圈里已经看不到熟悉的人的名字?某种意义上,逃离碎片化时间几乎等同于逃离微信。而与此同时,这些年又有大量的第三方应用,通过微信得到了巨大的流量红利,比如脸萌、天天P图、微信群助手、还有各种曾经刷爆朋友圈的H5小游戏,等等。这份蛋糕,微信其实也可以自己吃掉…… 无论出于防守还是进攻,微信都需要新的突破。小程序实际上是一种众包行为,通过第三方共同塑造一个更完整的微信生态,提供更多新的可能,也提供更多试错,根据用户反馈不断调整策略。微信在设计规范中明确提出不允许开发与现有服务类似的功能,也印证了这一观点。这对微信和第三方来说,都是一种双赢。 4、流量变现对于变现,微信一直做得很谨慎。然而开放小程序,使得微信可以较好地保护现有的用户体验,同时又增加出更多向B端实现流量变现的场景 5:“潜规则”:开发小程序少走弯路 小程序开发并非随心所欲,你需要看懂以下规则才能不走弯路: 1、小程序的功能定义与实际提供的服务必须一致;小程序所提供的类目,必须放置在首页,最深也只能放置在二级页面; 2、小程序所提供的服务目前暂时不能涉及游戏、直播等服务(涉黄涉赌就不用多说了)内容也不能涉及测试类内容;比如:算命,抽签,星座运势等; 3、小程序所提供的服务可以允许设置付费可见及隐藏可见(这点对于开发者来说可以发挥地方很多,具体在后面文章做详细论述); 4、小程序不能提供与微信现有功能相似的服务,如含朋友圈、漂流瓶等,也不能提供导航、排行榜、互推的服务; 5、小程序一如既往的不支持诱导分享、诱导关注,虚假欺诈等内容,也不支持广告展示比例超过50%的页面内容; 6、小程序不得诱导、泄露、转让用户的任何数据。所有行为都必须经过用户授权或有明显提示; 小程序这次真的来了,公测的时间比我们想象的要快,这也标志着微信小程序正式走向市场。正如张小龙所提到的,微信不仅仅是一个传播内容平台,更是服务平台,而小程序就是服务平台中最重要的体现。 作者:liujia216 授权地址:http://blog.csdn.net/liujia216/article/details/53182790
2016-11-17 - 【转】微信小程序:开发之前要知道的三件事
前言微信之父张小龙在年初的那次演讲中曾表示:“我自己是很多年的程序员,我觉得我们应该为开发的团队做一些事情”。几个月后,微信正式推出微信应用号(即微信小程序),在互联网中掀起了又一波热潮。 于是,很多人准备要开发微信的小程序,如果你真的想要开发小程序,就要先学会一套微信特制的“开发语言”。为了更好地上手这门开发语言,下面这三件事你一定要知道: 语言与文件微信小程序来发与其他平台开发的最大差异在于:微信使用的开发语言和文件很“个性”。 小程序所使用的程序文件类型大致分为以下几种: WXML(WeiXin Mark Language, 微信标记语言) WXSS(WeiXin Style Sheet,微信样式表) JS(JavaScript, 小游戏的主体) 在语言方面,下程序看似重新定义了一套标准。但实际上,他们与“前端三件套”(HTML、CSS和JavaScript)差不太多。来来来,看一下微信小程序开发语言和“前端三件套”的异同点。 [图片] 界面搭建1、基本逻辑WXML和WXSS两种文件是小程序界面元素声明及样式描述文件。 WXML最大的特点是以视图(View)的方式串联界面元素,并通过程序逻辑(AppService)将信息更新实时传递至视图层。 View类似于HTML中的div元素,在构建的时候,View可以被多级嵌套,View内可以放置任意视觉元素。 需要注意的是,元素一旦超出屏幕之外,用户就无法看到了,这是与HTML哟较大的不同。小程序哟专门用于滚动的视图。如果希望界面是一个可以自由滚动的界面(例如列表等),可以使用scroll-view视图,在WXSS中将其大小调整为整个屏幕,并设置scroll-y(上下滚动)或scroll-x(左右滚动)为true, 注意,小程序中不能直接使用DOM控制WXML元素。如果需要进行数据更新,就要使用WXML提供的数据绑定及元素渲染方法,还有一点,小程序的栅格排版系统使用的是Flex布局,它是W3C在2009年提出的一种排版标准。 2、绑定数据对于单个字段,开发者可以使用数据绑定的方法进行信息更新。绑定的数据除了在加载的时候可以更新,也可以在JS主程序中以函数形式进行更新,更新同样可以反应到界面上被绑定的数据中。 3、条件渲染与列表(循环)渲染条件渲染适用于有意外情况提示的页面(如无法加载列表或详情时,做出提示等等)。它的渲染带有触发条件,即符合条件时渲染这个页面,否则忽略或渲染另一端代码。两个花括号所包含的判断条件中的变量于主程序JS代码中的data中声明。将同一元素渲染代码进行集合。循环的数据可以通过数组的方式写入data中供WXML访问。渲染完毕后,渲染判断条件的变动可以影响界面变动。 4、模板与引用WXML支持使用模板与引用减少代码体积。模板是在WXML代码中对相同的代码进行复用的方式。可以将多个模板写入至同一个文件,并使用import在其他文件中进行引用。如果需要整个页面引用,需要使用include。 5、样式通过WXSS样式表,开发者可以定义WXML中的元素样式。WXSS与CSS代码一样,可以直接使用选择器选择元素,在WXML中也可以直接定义元素的id和class以便于在WXSS文件中进行样式定义。 6、用户操作与事件响应由于微信使用的不是HTML,所以也不能通过添加超链接(a元素)的方式来检测用户的点击事件。对于需要监听点击事件的元素,应该在WXML中使用bindtap属性或catchtap属性进行绑定。除了点击一次,微信也提供按住、开始触摸、松手等事件响应。在WXML中绑定好一个事件之后,就能在主程序中使用。其他的API中也有相应的事件,这些事件乐意在微信小程序的官方文档中查阅到。当需要在小程序的页面间进行跳转时,应该使用wx.navigateTo()方式。 注意,有关于页面层级跳转,微信将层级跳转限制在5层。在开发时一定注意不要超过了相应限制。 网络请求方式网络访问小程序支持三种请求方式:HTTP连接、WebSocket、文件收发连接。 HTTP连接:请求后直接返回结果,连接结束; Socket连接:持续性连接,当一方主动关闭连接时,连接结束; 文件收发连接:顾名思义,发生在文件传输时的连接。(录制的语音和选择的照片都需要这个连接完成)。 注意,通过小程序访问网络需要服务器必须支持HTTPS连接,且端口必须为443。同时,小程序只能访问开发者在登记小程序时设定的服务器地址。 开发语言和“前端三件套”的异同点 HTML与WXML:两者差异比较大,如果之前没有接触过Android开发,可能会觉得有些头疼。事实上,WXML更像是Android开发中的界面XML描述文件,适合于程序界面的构建;而HTML则倾向于文章的展示(这与HTML的历史有关),以及互联网页面的构建。 WXSS与CSS:两者在语言上几乎没有差别,可以直接通用。 JS文件:小程序的JS文件与前端开发使用的JS几乎没有区别,只是小程序的JS新增了微信的一些API接口,并去除了一些不必要的功能(如DOM)。 在有眼上,小程序完全向学习成本最低的前端开发看齐,但这不代表所有开发者都能无缝迁移。如果你是从前端开发转向小程序,就要注意这两点: 1、HTML与WXML两种文件的构建思想差异较大,如果之前只接触过前端开发,需要一点时间才能适应WXML的编写方法。 2、虽然小程序使用的是前端语言,但不代表可以继续沿用的开发思想进行开发。小程序对前端开发的要求从【构建界面】升级成【开发完整应用】,前端开发需要在意识上进行转变。 原作者:liujia216 授权网站:http://blog.csdn.net/liujia216/article/details/53162385
2016-11-17