前言
首先我要声明,我是一名开发者,基本没有前端开发经验,就连 JS、HTML 也只是为了开发小程序而学的一些皮毛玩意儿。所以文章中提到的一些点,在资深前端开发者眼里可能只是小case,但站在一个开发者的角度,确实是大坑。
开头就不说太多了,文章最后我会说一下自己对小程序的看法,这篇文章主要讲一下在开发小程序过程中遇到的一些坑。
PS:给大家推荐一个我写的微信小程序版的Gank客户端:--gank
动态图
文本1:获取小程序开发工具并正确安装?
最近看到很多人在一些地方入坑第一步就遇到很多问题,其实很早之前(22号)已经有比较好的关于如何获取小程序开发工具的资料了,大家可以看看然后照着做,基本不会有问题:小程序开发工具获取及正确安装教程
2.直接在微信开发工具上写代码?
目前我们只能在微信的开发工具上编写小程序的代码,但这并不意味着我们必须在那个开发工具上编写小程序的代码。用过那个开发工具的人就会知道,那个开发工具不太好用,代码提示相当弱,没有自动保存是一个致命的缺陷。
那我们可以怎么做呢?我们可以在其他工具中编写代码,然后在小程序的开发工具中编译。我试过 和 ,都可以在上面开发,但最后发现 ws 更好用。如何使用就不多说了,直接在里面打开项目文件夹,点击右下角选择当前语言就可以了。接下来我重点讲解一下如何在 ws 中编写小程序代码。
首先,选中小程序的目录,在ws中打开,这个很简单。但是打开里面的文件之后,你会发现,除了js代码之外,它无法识别其他的代码——主要是.wxml和.wxss文件。为什么呢?因为虽然.wxml和.html文件很相似,而.wxss文件又和.css文件很相似,但是编译器却不认识!这样一来,我们就无法在这两个文件中享受到ws强大的代码提示功能——我们能接受吗?肯定不能!那么接下来我们该怎么做呢?告诉编译器,.wxml格式其实是HTML文件,.wxss格式其实是CSS*文件。
告诉编译器*.wxml*实际上是一个*HTML*文件
上图详细介绍了这样做的过程,.wxss 文件的转换也是一样。这样做完之后编辑器就知道它们的真实样子了,然后就可以有很棒的代码提示了(不过请注意,如果你写的东西是微信写的东西,编辑器不但不会提示代码而且会报错,不用管它就行)!接下来你就可以直接 ws 桌面小程序开发工具 a 桌面了,在 ws 里写好代码直接点编译就可以了。
3.跳转页面时如何传递数据?
小程序给我们提供了良好的页面跳转接口:
界面间跳转
但是微信官方对这个接口并没有太多的说明,只是给了我们一行代码:wx.({url: "test ? id = 1"});,有点看不懂,test 又是什么鬼?id 又是什么鬼?中间的问号又是什么鬼?这都是些什么鬼?
反正我看到的时候也是一头雾水。不过还好,经过一番探索,我终于搞清楚了它们是什么。首先,代码中的 test 代表要跳转的页面的 URL 地址。例如:
跳转到此页面
那么代码应该是:
wx.navigateTo({url: "/pages/specific/specific"});
聪明的人可能已经发现,上面的代码在示例代码中没有 ?id = 1 这部分。怎么回事?是我写错了吗?不是的。这部分其实是跳转页面时用来传值的关键方法。不是必须的,但是很有用。
** ? 是分隔符,它后面都是要传递给目标页面的值,这些值通过键值对一一匹配,每个键值对之间用&分隔。但要注意的是,这种方式好像只能传值,不同类型的值传递后会进行转换。**比如我传递了一个json:
var arrayData = ["firstData" , "secondData"]; var jsonData = {first: "firstData" , second: "secondData"}; wx.navigateTo({url: "/pages/specific/specific ? data: " + arrayData + "&json=" + jsonData});
目标页面接收到的结果为:
//目标page的onLoad方法 onLoad: function (options) { //结果是:firstData , secondData console.log(options.data); //结果是:f console.log(options.data[0]); //结果是:[object Object] console.log(options.json); //结果是:undefined console.log(options.data.first); //很显然,被转化了 }
上面其实也演示了在目标页面中如何接收传递的数据,在()中获取即可。
另外,其实更多时候我们的需求并不是直接传递一个固定的参数给目标页面,而是根据一些用户操作,传递不同的值给目标页面。这时候我们该怎么办呢?要知道,我们是没有办法拿到组件的(这个太坑爹了,没有and),这时候我们可以通过绑定组件数据来达到目的。啥?你不知道是什么吗?
多读书,多看报,多看文献,少睡觉。
4.有些图片无法加载?
这个坑真的是一个很深的坑,你可能很长时间都不会碰到,但是一旦碰到了,那真的非常痛苦。
我用来练习的项目是Gank.io客户端,而Gank官网上的图片全部存储在新浪图片托管上,默认存储url为{1 || 2 || 3 || 4}…jpg,而我无论如何都无法在小程序中加载这些图片!!!
一开始不知道是小程序标签的问题还是图片的问题,就找了很多地方的图片来测试,包括CSDN、简书、图程等。结果这些图片都能正常显示——连新浪微博上有些人的头像都能显示!后来发现,只要是以ww+数字开头的URL,图片就无法正常显示!这也太坑爹了……后来我就想着怎么解决这个问题——要么改标签,标签肯定有问题,可能对某些来源的图片不友好;要么改图片,让它适应这个标签。这两方面其实都挺难改的,但显然第一种方法基本行不通,只能在第二种方法上下功夫了。
最后经过不断的尝试,我总结了很多规律,最终通过将图片的 URL 由 ww+ 改为 ws+,让图片可以在小程序上展示,解决了这个问题。例如:
本来的URL: http://ww1.sinaimg.cn/large/610dc034jw1f87z2n2taej20u011h11h.jpg 变换之后的URL: http://ws1.sinaimg.cn/large/610dc034jw1f87z2n2taej20u011h11h.jpg
不要问我为什么这样改了之后就能显示,因为我也不知道。。。神奇。。
5.this.()表明没有这个方法?
首先,作为一名开发者,我对小程序中数据与控件的绑定方式不是很习惯,开发时我们可以直接获取控件然后对其进行数据绑定,但在小程序中我无法直接获取控件对象,所有数据绑定和动态修改只能通过在Page中维护data{}并调用()方法来完成,我不太擅长判断这两种方式的优劣,只能说是真的不太习惯。
但是一些像我这样之前没有接触过前端开发的朋友在这样做的时候可能会陷入一个陷阱 —— *() 是 Page 级别的方法,在任何地方调用 this.() * 方法都无法顺利得到预期的结果。例如:
Page({ onLoad: function (options) { wx.request({ url: Constant.GET_URL, success: function (res) { this.setData({...}); } }); }, });
当我在wx.()的回调接口中写上this.({...})时,无法完成预期的操作。程序会报错说没有()方法,因为此时this已经不再是Page了,上下文已经发生了变化,所以当前层级没有()方法是正常的。那么如何解决这个问题呢?像这样:
Page({ onLoad: function (options) { that = this; wx.request({ url: Constant.GET_URL, success: function (res) { that.setData({...}) } }); }, }); var that;
和开始不同的是多了一个全局变量that,并在()方法中给它赋值,让它等于this。这样,我们就可以在这个Page的任何地方调用that.()来动态改变控件的属性。
结论
还有一些问题我想讨论,但文章已经很长了,所以我将把其他问题放在下一篇文章中。剩下的问题是:
接下来我想谈谈我对小程序的看法。
感谢您阅读本文,请给我一颗星:--gank