如果你未指定 Node.js 的版本时,会以 0.10.2 版本 运行,此版本无法使用 const ,所以,需要指定你的 Node 版本。
分类目录归档:技术
WePy 整合云开发
由于工作上的原因,有需求要使用 WePy,刚好,有了云开发的契机,就决定研究一下。
初试 WePY
想要做云开发和 WePY,首先要先熟悉 WePY。 WePY 其实之前就听说过,不过自己一直没有使用,更多还是习惯用小程序原生写法来进行开发。
后续,也用过一些其他的框架,比如 MinUI 。
和 MinUI 相比,WePY 给我来说最大的感受是提供了 promise 的支持和 async/await 的支持,这个支持可以极大的改善 JavaScript 编程时遇到的 Callback Hell 的问题,可以让我们更加愉悦的开发。
此外,我比较看重的特性是支持外部的 NPM 包,支持 NPM 包意味着可以更好的使用 JavaScript 原本的工程化的产品,也是大大提升生产力的特性。不过,相比于 Promise 的支持和 async/await 的支持,这个如今已经被微信小程序官方团队所支持的 npm 也显得不那么重要了。
做一个 WePY 的 tempalte 吧!
在看文档时注意到,WePY 是使用 wepy init 来进行初始化的,而且可以使用 wepy list 来查看项目的模板。发现了其中有一个基于 ZanUI 的模板。
由于 ZanUI 及更名后的 VantUI 我都比较熟悉,所以从他下手,去研究一下如何制作 WePY 的模板。

复制 repo名/模板名,并在前面加上 github 的域名,就找到了对应的 repo 。
简单的看了一下项目的文件,发现其中并没有什么特殊的,需要指明初始化内容的文件,所以猜测大概率是不需要进行单独的配置的。
这方面 WePY 的文档做的不是很好,我在文档中并没有找到相关的说明。如果可以的话,希望开发者可以加一个功能,比如加上一个 .wepy-template ,可以在里面加入一些交互式的问题,从而来让用户设置一些内容。
在确定了模板其实并不困难以后,我就开始做自己的云开发模板了。
如何做一个模板
做一个模板只需要三步
- 下载官方的 empty 模板
- 加入你自己的代码
- 上传到 Github
说起来简单,不过,在实际制作时,还是应当注意一些问题:
- 初始化 Empty 模板后,尽快使用
git init来初始化版本控制。这是因为云开发是与小程序的 AppID 进行绑定的,如果前期没有做好控制,容易出现后续将 AppID 加入了版本追踪。所以在一开始,我就将项目进行了初始化,方便后续的回溯。 - 上传到 Github 时,应当注意配置 Readme,在我之前的文章中,曾经提到过我们应当尽可能的交付一些产品给世界,好让世界根绝我们所交付的产品进行估值。特别是对于模板类型的 repo ,更是需要一个非常好的 Readme ,来引导别人去使用自己的模板
- 制作完成模板后,记得自己使用
wepy init命令将整个过程完整的走一遍。确保你的模板是可用的。
在使用 WePY 过程中遇到的一些问题
CloudFunctionRoot 的设定问题
在做第一个版本的时候,我是将云函数的目录放在 src 目录下,后续,在运行时发现, WePY 会自动编译云函数的目录,导致出错。不得已,我将云函数的目录放置在了项目的根目录。
当时在研究这部分时,我试图去寻找 wepy.config.js文件的配置说明,希望找到一个 exclude 配置项目,来忽略一部分目录,可惜,我并没有找到。
WePY 下的一些定义问题
在使用原生写法的时候,我常常会在 Page({}) 函数外部放上一些引用。比如这样
const database = wx.cloud.database()
const storeCollection = database.collection('store')
Page({
onReady():function(){
// some code
}
})
在 WePY 中我试图将代码放在 Page 实例的内部,不过会导致报错,因此,我不得不废弃这样的写法,改用 constructor 来实现。
export default class Index extends wepy.page {
constructor () {
super()
this.db = wx.cloud.database()
}
onLoad() {
console.log('onLoad')
console.log(this.db)
}
}
对 getApp 报错
在 WePY 中,由于传承了 Vue 的思想,并没有提供对 getApp的 hack ,不过在实际的测试过程中,发现 getApp() 依然可用。
如果不引入 Redux 之类的状态管理工具的情况下,getApp() 的单例模式作为一个全局的 Bus 来进行数据的传递还是非常方便的。
关于 WePY 的其他
总的来说, WePY 是一个值得尝试的框架,单纯 Async/Await 的引入,可以让你的代码变得更加简洁易懂。特别是如果你的项目需要长期运转的情况下,整洁的代码会帮助你的项目成功。
此外,如果你很习惯于 Vue 的写法,那么 WePY 不容错过,computed 属性还是非常实用的。
小程序的 marker 无法触发 bindmarkertap 事件应该如何处理
TL;DR
如果想要 marker 可以响应 bindmarkertap 事件,需要设定 marker 的 ID,这一点文档中并没有标注。
具体情况
在开发美食地图时,出现了一个问题,marker 的点击总是不会触发 bindmarkertap 事件。
我的代码是这样写的
store.get().then(res => {
this.setData({
stores: res.data,
windowHeight: app.globalData.windowHeight,
}, () => {
wx.hideLoading();
wx.showToast({
title: '双指缩放可以调整地图可视区域,查看更多美食',
icon: 'none'
})
})
})
Code language: JavaScript (javascript)在地图中去调用 stores. marker 。
在地图上的确可以出现图标,但是无法点击 maker 并触发事件。
通过复制官方的 marker 的数据进行调试后发现,当 maker 有 id 时,marker 就可以触发事件,因此,怀疑是 ID 的问题。
在美食地图小程序中,我使用的是腾讯云提供的小程序·云开发,其使用的是 MongoDB 作为后台的 Database ,默认的主键为 _id,所以,我自己写了代码来转换 _id。
data.map(item => {
item.id = item._id
});
Code language: JavaScript (javascript)为什么 Rails 运行 Generate 命令会很慢
TL;DR
因为 Rails 命令使用的 Spring 已经在运行了,你需要执行
spring stop来停止掉 Spring ,就可以继续执行了。
详细内容
参考:https://stackoverflow.com/questions/24096262/ruby-on-rails-rails-generate-controller-does-not-work
实现密码生成器的思路
在项目中有这样一个需求:需要生成一组随机密码,确保安全性。因此,我去翻了一个项目的代码。这里是具体的代码
function GeneratePassword() {
if (parseInt(navigator.appVersion) <= 3) {
alert("Sorry this only works in 4.0+ browsers");
return true;
}
var length=8;
var sPassword = "";
length = document.aForm.charLen.options[document.aForm.charLen.selectedIndex].value;
var noPunction = (document.aForm.punc.checked);
var randomLength = (document.aForm.rLen.checked);
if (randomLength) {
length = Math.random();
length = parseInt(length * 100);
length = (length % 7) + 6
}
for (i=0; i < length; i++) {
numI = getRandomNum();
if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } }
sPassword = sPassword + String.fromCharCode(numI);
}
document.aForm.passField.value = sPassword
return true;
}
function getRandomNum() {
// between 0 - 1
var rndNum = Math.random()
// rndNum from 0 - 1000
rndNum = parseInt(rndNum * 1000);
// rndNum from 33 - 127
rndNum = (rndNum % 94) + 33;
return rndNum;
}
function checkPunc(num) {
if ((num >=33) && (num <=47)) { return true; }
if ((num >=58) && (num <=64)) { return true; }
if ((num >=91) && (num <=96)) { return true; }
if ((num >=123) && (num <=126)) { return true; }
return false;
}
Code language: JavaScript (javascript)上完代码,接下来来分析一下这段代码
首先,这段代码中有三个函数,其关系如下图所示

其中 getRandomNum 生成了一个范围在 33 – 127 的数字。这里是由于在后续生成随机字符串时,用的是 String.fromCharCode,当数字在 33~127 之间时,能够确保生成的数字在输入时比较简单。

而 checkPunc 则是检测输出的文字是否可以直接发音,这涉及到记忆的难度的问题,在一个长的字符串中,记忆 ABCD 肯定比记忆逗号、破折号、句号等符号要简单一些,毕竟字母肯定要好记忆点,可以自编语句来实现。
接下来我们来看最核心的 GeneratorPassword 函数:如果将其中的 Dom 操作都忽略掉,并设置一个值。并进行配置后,代码如下:
function GeneratePassword() {
// 检测浏览器支持
if (parseInt(navigator.appVersion) <= 3) {
alert("Sorry this only works in 4.0+ browsers");
return true;
}
var length=8;
var sPassword = "";
length = 10 // 此处代码原为使用 dom 函数获取表单数据的代码,来实现自定义长度的功能。
var noPunction = false// 此处代码原为获取表单数据的代码,控制是否检测密码的可读性
var randomLength = false // 此处代码原为获取表单数据的代码,控制是否使用随机长度。
// 如果使用随机长度的密码,则进入循环
if (randomLength) {
length = Math.random();
length = parseInt(length * 100); // 生成 0 ~ 100 之间的数字
length = (length % 7) + 6 // 对生成的长度取余,则最短为6,最长为12
}
// 根据长度进行循环
for (i=0; i < length; i++) {
numI = getRandomNum(); // 获取一个随机数
if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } } // 如果需要判断发音,进行发音判断,判断失败就重新生成,直到成功。
sPassword = sPassword + String.fromCharCode(numI); // 将生成的字符串加入到原有的字符串最后
}
// 设置代码到 Dom 元素中
return true;
}
Code language: JavaScript (javascript)其代码逻辑图如下

第三方服务前端数据安全校验
坐在腾大写博客,听到了身边的人在讨论前端数据安全校验的方案。
他们需要提供 H5 的SDK ,既然运行在前端,那么应用的 Secret 和 Key 就有可能暴露在浏览器里,如何确保 Secret 和 Key 的安全呢?
一个比较主流的方案就是使用白名单限制。每一个应用绑定特定的几个域名,只有白名单里的域名可以请求服务。
我还想到了另外一个案例。我自己比较喜欢使用 Algolia 提供的搜索服务,在 Algolia 中,区分 Master Key 和 Search Only Key。Search Only Key 只能用于数据查询,而 Master Key 可以用来添加数据。
如果是这样的话,或许可以比较好的处理。
如何保持对技术的敏感性?
我有个习惯:做 Side Project
我还有个习惯:每次做 Side Project,使用不同的技术。
举个例子:
我经常会做和 web 相关的项目,第一个项目我使用 Laravel (Php)开发;第二个项目我就考虑使用 Rails (Ruby)开发;第三个项目就用 Django(python) 开发。
这样、只要 Side Project 不死,我就需要经常维护,对我来说,就是保持自己一直掌握这些技能,不会丢掉技能。
好看的 TextFieldEffects 要怎么用?
软件工程最大的好处便是可以系统集成。对于一个新手来说,集成各种组建自然是最好的选择。这里我便来集成 TextFieldEffects。
这个包是由 Raul Riera 开发的,源码在 https://github.com/raulriera/TextFieldEffects
PHP 检测 空 Object
if (empty((array) $obj)) {
return 'error';
}PHP 对比 float 型
if (abs($dem)=== 0.00){
//true
}
参考链接:http://php.net/manual/en/language.types.float.php