微信小程序由于适用性强、逻辑简要、开发迅速的特性,叠加具有海量活跃用户的腾讯公司背景,逐渐成为了轻量级单一功能应用场景的较佳承载方式,诸如电影购票、外卖点餐、移动商城、生活服务等场景服务提供商迅速切入了。
为了贴合实际的应用情况,本篇以豆瓣评分小程序为参考样例,边做边学小程序的入门开发知识。
目录
主页
首先是index.wxss文件,一行代码导入block模板的wxss:
然后是index.wxml文件:
这是首页作为静态页面的全部代码,通过导入block模板,在for循环中取出“正在热映”、“即将上映”和“排行榜”三个区块的数据,散开传入模板即可。
threeBlockInfo是我们在index.js文件的data中自定义的数组变量名,用来存放三个区块的标题和滑动条中的电影信息。这个数据是通过请求网络动态加载的。
网络请求
接下来我们先看看小程序的网络请求相关的知识。
wx.request()是小程序官方封装的网络请求API,它有诸多的其它的参数,这里我们只用了最简要的参数,url表示你要请求的网址,success表示请求成功后的回调(为简便,这里忽略fail等情况)。
小程序中有多处地方需要用到网络请求,因此我们将这个网络请求简单的封装一下,以便多处调用。
在utils目录下新建httpUtil.js文件,并写入:
这里封装了2个网络请求方法,一个是常规请求,一个是三个区块的请求(通过传入不同的key来识别对应的区块,以便在回调中存储返回值到对方的变量中,可能暂时不好理解,稍后看后文的用法一看并知)。
通过module.exports向外暴露方法名,并在需要使用的文件中导入本js文件,方可调用到这2个方法。
另外在utils目录中新建一个stringUtils.js文件,这是一个工具类,处理电影名称过长等情况,可以不必理解代码含义,复制过去即可。代码如下:
打开app.js文件,定义一个全局变量baseUrl,值为接口的基本网址。
注意,app.js最外层为App({}),各个页面的js文件是Page({})。
因豆瓣近期关闭了面向个人开发者的API接口功能,本篇目前采用一家第三方接口(t.yushu.im)提供的数据,其并未提供搜索功能的接口,因此暂时无法实现官方小程序中含有的搜索功能。
Tips:第三方接口仅供学习使用,请勿滥用;并且可能随时停止服务,请勿用在正式产品中。
因为小程序要求网络请求的域名必须为https安全链接,这里开发用的接口网址没有https证书,因此需要点击开发者工具顶端的菜单“设置”—“项目设置”,勾选“不校验安全域名”项。但是,正式发布的小程序所使用的网络请求中,接口网址必须为https类型。
逻辑实现
在index.js文件开头写入:
在这里导入了网络请求和字符处理工具类,这样就可以调用工具类中module.exports向下暴露的方法。通过系统提供的getApp()方法获得APP实例app,之后可以用app调用APP的相关方法。
在data中定义一个变量threeBlockInfo,内含三个空键值对,用来存放首页三个区块网络请求后的数据。
小程序每个页面存在着生命周期,例如页面首页加载时会触发onLoad(options)方法,在这里我们可以做网络请求的工作。
首先通过APP实例app获取到app.js文件中globalData里定义的基本网址,然后拼接出三个区块的接口网址。
通过网络请求工具类中向外暴露的方法去获取三个区块的数据。如果请求成功,将回调processResult()方法,我们在后面继续实现这个回调方法。(这里仅作演示用,未对请求不成功等情形做分支处理,可根据业务自行处理逻辑。)
这里我们先后发起了三次请求,分别去获取对应的数据,但回调未必会按顺序返回,可能后发起的请求先返回数据。如何在回调中区分是哪个区块的数据呢?这里传入的第二个参数key分别为hot/recent/top250,便是识别标识,用途看下文。
请求数据成功后,将对应的数据和其标题存入对应的threeBlockInfo[key]中。例如排行榜top250的数据和标题“排行榜”,将存入threeBlockInfo[top250]中,键名分别是blockMovies和blockTitle,如此,三个区块的数据无论哪个请求先返回数据,都会存入对应的键值对中,互不影响,同时保证了threeBlockInfo本身是有序的。
setData
然后,通过this.setData的方式,将threeBlockInfo的数据更新并重新渲染界面。
注意:小程序官方警告不要用“=”号赋值,这样并不会重新渲染界面,会导致用户在前台看到的数据和实际内存中的数据不一致。因为渲染界面属于耗时操作,不要频繁地setData,当页面在后台时,也没必要setData。
接下来,我们实现电影详情页。当我们在首页点击某个电影海报时,可以跳转到这部电影的详情页。我们来看获取电影详情页的接口网址。
显然,当我们点击首页电影时,要将点击的电影的id带到详情页,这样详情页才知道去请求哪部电影的数据。
那么,如何将数据带过去呢?
点击事件
我们回到poster.wxml中,在这个海报模板里,曾经有一行代码我们还没有讲解,如下:
catchtap正是点击事件属性,名为catchTapMovie,我们需要在调用处index.js中实现这个方法。
在点击行为发生后,系统为我们封装了点击控件的一些数据在event中。dataset.movieid便是从data-movieid里获取的值。
注意,无论是data-movieId,还是data-movieid,都用dataset.movieid(小写)接收;无论是data-movie-id或data-movie-ID,都用dataset.movieId(I大写d小写)接收。即不带“-”号的,都会转为小写;带“-”号的多字符,每个“-”号后的首字母变成大写(非首字母变小写),并与其它单词合并在一起。这里是大小写敏感的,变量名不一致将接收不到数据。
详情页
然后,在电影详情页detail.js的onLoad方法中接收参数,如下(请在movies目录下新建detail目录和detail页面,并在app.json的pages中配置路径)。
通过options.movieId接收到从首页带过来的movieId变量的值,拼接成接口网址后,请求获取电影信息,并在成功后回调processResult方法。
在此之前,我们先实现电影详情页的页面结构和样式。
detail.wxml代码如下:
detail.wxss代码如下:
在wxml中通过{{}}的方式绑定了一个变量,我们回到detail.js文件中定义这些变量并且实现剩下的业务逻辑。
然后接着实现刚才网络请求成功后的processResult回调方法。
按Ctrl+S保存后,快试试首页是否可以点击电影海报到详情页吧。
更多页
依葫芦画瓢,来实现首页点击“更多”按钮到更多页。首先在movies目录下新建more目录和页面,并在app.json的pages中配置页面路径。然后在block.wxml中找到“更多”按钮的点击事件名称及数据属性名。
通过title接收区块名称,点击事件为catchMore。在调用处index.js中实现吧。
在more.js的onLoad方法中接收传入的区块标题。
先来看看更多页more.wxml的页面结构。
更多页more.wxss的样式代码:
和首页类似,这里使用了一个控件,不过是竖向的,有一个名为loadMore的bindscrolltolower事件(滑动到底部),当页面滑动到底部时,将触发此事件,我们在js的这个事件里实现“滑到底部加载更多”的逻辑。(页面还有“上拉加载更多”事件,也可试试用这个方法实现)
在more.js代码中,有如下代码:
别忘了,此页面的海报也是可以点击进入到电影详情页的,很简单,和主页一样,在more.js里实现点击事件,携带movieId到detail即可。
到这里,我们边做边学了小程序开发最基础的一些入门知识,如页面配置、tabBar配置、模板页面、点击事件、网络请求与回调等,并能成功地独立完成一个较为简单的作品。
扩展知识
控件的点击事件有2种,除了文中出现的catchtap,还有bindtap事件。这两种事件的使用场景有什么区别呢?我们来看个小例子:
这里定义了两个嵌套的控件,内部使用了catchtap,外部则使用了bindtap。当我们只点击内部控件时,只会触发innerTap事件,外部控件的outerTap事件是不会触发的。而将catchtap改为bindtap后,外部控件的outerTap事件也能够触发。可见,bindtap不会阻止事件向外层(父层)传达,而catchtap则不同,会将事件捕获在本层,不再向外传达。
思考题
也许你注意到了,在控制台总是在有wx:for循环的地方会出现下图的提示,尝试去搜索下答案吧?
纯文笔记
记录知识,分享心得。
领取专属 10元无门槛券
私享最新 技术干货