在学习微信小程序开发过程中,一部分的难点是前端逻辑的处理,也就是对前端JS的代码编辑;一部分的难点是前端界面的设计展示;本篇随笔基于一个豆瓣电影接口的小程序开源项目进行重新调整,把其中遇到的相关难点和改进的地方进行讨论介绍,希望给大家提供一个参考的思路,本篇随笔是基于前人小程序的项目基础上进行的改进,因此在开篇之前首先对原作者的辛劳致敬及感谢。

1、豆瓣电影接口的小程序项目情况

豆瓣电影接口提供了很多相关的接口给我们使用,豆瓣电影接口的API地址如下所示:https://developers.douban.com/wiki/?title=movie_v2

在GitHub的开源库里面,可以搜索到很多关于豆瓣电影接口的小程序,我本篇随笔是基于 weapp-douban-movie 这个小程序进行的改造处理,后来找到了原作者的项目地址:wechat-weapp-movie,原作者对版本做了一次升级,后来我对照我的调整和作者最新版本的源码,发现有些地方改造的思路有些类似,如对于URL地址外放到统一的配置文件中的处理,不过还是有很多地方改造不同。

本篇随笔的改造方案是基于小程序项目 weapp-douban-movie 的,因此对比的代码也是和这个进行比较,不知道这个版本是不是原作者的旧版本,不过这个版本对文件目录的区分已经显得非常干净利落了,对电影信息的展示也统一到了模板里面,进行多次的重复利用,整体的布局和代码都做的比较好,看得出是花了不少功夫进行整理优化的了。

小程序主界面效果如下所示:

小程序源码目录结构如下所示:

不过每个人都有不同的经验和看法,对于开发小程序来说,我侧重于使用配置文件减少硬编码的常量,使用Promise来优化JS代码的使用,将获取和提交JSON数据的方法封装到辅助类,以及使用地理位置接口动态获取当前城市名称和坐标等等。

本篇随笔下面的部分就是介绍使用这些内容进行代码优化的处理过程。

1、使用配置文件定义常量内容

我们在使用任何代码开发程序的时候,我们都是非常注意一些变量或常量的使用,如果能够统一定义那就统一定义好了,这种在小程序的JS代码里面也是一样,我们尽可能抽取一些如URL,固定参数等信息到独立的配置文件中,这样在JS代码引入文件,使用变量来代替

例如原来的config.js文件里面,只是定义了一个地址和页面数量的大小常量,如下所示

  1. module.exports = {
  2. city: '杭州',
  3. count: 20
  4. }

原来的小程序代码在获取待映的电影内容时候,部分源码如下所示

其他页面JS代码也和这个类似,头部依旧有很多类似这样URL地址,这个是我希望统一到config.js文件的地方,另外这个调用的函数是使用回调函数的处理方式,如下所示。

  1. douban.fetchFilms.call(that, url, config.city, that.data.start, config.count)

其实我认为这里面既然是定义的外部函数,那么这里面的url, city, config.city, config.cout都不需要这里,在封装函数内部使用这些常量即可,因此可以对他们进行改造,如下我们统一抽取各个文件里面的URL,以及一些常见变量到config.js里面。

下面代码是我优化整理后的配置参数信息。

  1. module.exports = {
  2. city: '',
  3. location:'0,0',
  4. count: 20,
  5.  
  6. coming_soon_url: 'https://api.douban.com/v2/movie/coming_soon',
  7. in_theaters_url: 'https://api.douban.com/v2/movie/in_theaters',
  8. top_url: 'https://api.douban.com/v2/movie/top250',
  9. search_url: 'https://api.douban.com/v2/movie/search?tag=',
  10. detail_url: 'https://api.douban.com/v2/movie/subject/', //?id=
  11. celebrity_url: 'https://api.douban.com/v2/movie/celebrity/',
  12. baidu_ak:'6473aa8cbc349933ed841467bf45e46b',
  13. baidu_movie:'https://api.map.baidu.com/telematics/v3/movie',
  14.  
  15. hotKeyword: ['功夫熊猫', '烈日灼心', '摆渡人', '长城', '我不是潘金莲', '这个杀手不太冷', '驴得水', '海贼王之黄金城', '西游伏妖片', '我在故宫修文物', '你的名字'],
  16. hotTag: ['动作', '喜剧', '爱情', '悬疑'],
  17. }

上面的配置文件config.js里面,我统一抽取了各个页面的URL地址、关键词和标签(hotKeyword和hotTag)、城市及地址(city和location后面动态获取)、页面数量count等参数信息。

另外由于部分参数统一通过config.js获取,就不需要再次在调用的时候传入了,因此简化调用代码的参数传入,如下代码所示。

  1. douban.fetchComming(that, that.data.start)

对于原先的代码

  1. douban.fetchFilms.call(that, url, config.city, that.data.start, config.count)

简化的虽然不多,但是尽可能的保持干净简单的接口是我们的目标,而且这里把常规的URL等参数提取到函数里面,更加符合我们编码的习惯。

这里定义的douban.fetchComming(that, that.data.start) 使用了Promise来简化代码,传入的that参数是因为需要在函数体里面设置该页面里面的Data等处理。

关于Promise的相关处理,我们在下面进行介绍。

2、使用Promise来优化JS代码

关于Promise的好处和如何使用Promise插件介绍,我在随笔《在微信小程序的JS脚本中使用Promise来优化函数处理》中已有介绍,我很喜欢使用这种Promise的风格代码,而且可以定义一些常用的辅助类来提高代码的重用。在我参考的这个豆瓣电影小程序还是使用常规回调的函数,对比原作者最新版本的 wechat-weapp-movie 小程序,也依旧使用回调函数模式来处理,有点奇怪为什么不引入Promise插件来开发。

原来的小程序,电影接口的相关处理,统一在fetch.js里面进行处理,这里封装对各种豆瓣API接口的调用。

这里我们来看看原来程序没有采用Promise的回调函数处理代码

  1. var config = require('./config.js')
  2. var message = require('../../component/message/message')
  3.  
  4. module.exports = {
  5. fetchFilms: function(url, city, start, count, cb) {
  6. var that = this
  7. if (that.data.hasMore) {
  8. wx.request({
  9. url: url,
  10. data: {
  11. city: config.city,
  12. start: start,
  13. count: count
  14. },
  15. method: 'GET',
  16. header: {
  17. "Content-Type": "application/json,application/json"
  18. },
  19. success: function(res){
  20. if(res.data.subjects.length === 0){
  21. that.setData({
  22. hasMore: false,
  23. })
  24. }else{
  25. that.setData({
  26. films: that.data.films.concat(res.data.subjects),
  27. start: that.data.start + res.data.subjects.length,
  28. showLoading: false
  29. })
  30. }
  31. wx.stopPullDownRefresh()
  32. typeof cb == 'function' && cb(res.data)
  33. },
  34. fail: function() {
  35. that.setData({
  36. showLoading: false
  37. })
  38. message.show.call(that,{
  39. content: '网络开小差了',
  40. icon: 'warning',
  41. duration: 3000
  42. })
  43. }
  44. })
  45. }
  46. },

这个函数是一个通用的函数,用来获取待映、热映、top250口碑的记录信息,不过它把参数抛给调用者传入,因此显得调用比较复杂一些,我们经过使用Promise优化代码处理,并对接口的参数进行简化,代码改造如下所示。

  1. var config = require('./config.js')
  2. var message = require('../../component/message/message')
  3. var app = getApp()//获取应用实例
  4.  
  5. module.exports = {
  6. //待映
  7. fetchComming : function(page, start) {
  8. return this.fetchFilms(page, config.coming_soon_url, config.city, start, config.count);
  9. },
  10. //热映
  11. fetchPopular : function(page, start) {
  12. return this.fetchFilms(page, config.in_theaters_url, config.city, start, config.count);
  13. },
  14. //top250口碑
  15. fetchTop : function(page, start) {
  16. return this.fetchFilms(page, config.top_url, config.city, start, config.count);
  17. },
  18.  
  19. //通用的热映、待映的获取方式
  20. fetchFilms: function(page, url, city, start, count) {
  21. return new Promise((resolve, reject) => {
  22. var that = page;
  23. var json = {city: city, start: start, count: count };
  24. var type = "json";//特殊设置,默认是application/json
  25. if (that.data.hasMore) {
  26. app.utils.get(url, json, type).then(res => {
  27. if(res.subjects.length === 0){
  28. that.setData({
  29. hasMore: false,
  30. })
  31. }else{
  32. that.setData({
  33. films: that.data.films.concat(res.subjects),
  34. start: that.data.start + res.subjects.length,
  35. showLoading: false
  36. })
  37. }
  38. wx.stopPullDownRefresh();
  39.  
  40. resolve(res);
  41. })
  42. }
  43. })
  44. },

最终的请求接口参数只有两个,一个是页面对象,一个是请求的起始位置,如下代码所示

  1. function(page, start)

另外我们使用了代码

  1. app.utils.get(url, json, type)

来对wx.request方法的统一封装,直接使用工具类里面的方法即可获取结果,不需要反复的、臃肿的处理代码。这就是我们使用Promise来优化JS,并抽取常用代码到工具类里面的做法。

我们再来对比一下获取电影详细信息的接口函数封装,原来代码如下所示。

  1. fetchFilmDetail: function(url, id, cb) {
  2. var that = this;
  3. wx.request({
  4. url: url + id,
  5. method: 'GET',
  6. header: {
  7. "Content-Type": "application/json,application/json"
  8. },
  9. success: function(res){
  10. that.setData({
  11. filmDetail: res.data,
  12. showLoading: false,
  13. showContent: true
  14. })
  15. wx.setNavigationBarTitle({
  16. title: res.data.title
  17. })
  18. wx.stopPullDownRefresh()
  19. typeof cb == 'function' && cb(res.data)
  20. },
  21. fail: function() {
  22. that.setData({
  23. showLoading: false
  24. })
  25. message.show.call(that,{
  26. content: '网络开小差了',
  27. icon: 'warning',
  28. duration: 3000
  29. })
  30. }
  31. })
  32. },

我改造后的函数代码如下所示。

  1. //获取电影详细信息
  2. fetchFilmDetail: function(page, id) {
  3. return new Promise((resolve, reject) => {
  4. var that = page;
  5. var url = config.detail_url + id;
  6. var type = "json";//特殊设置,默认是application/json
  7. app.utils.get(url, {}, type).then(res => {
  8. that.setData({
  9. filmDetail: res,
  10. showLoading: false,
  11. showContent: true
  12. });
  13.  
  14. wx.setNavigationBarTitle({
  15. title: res.title
  16. });
  17. wx.stopPullDownRefresh();
  18.  
  19. resolve(res);
  20. });
  21. })
  22. },

通过对fetch.js函数代码的改造处理,可以看到调用的JS代码参数减少了很多,而且页面也不用保留那么多连接等参数常量信息了。

  1. onLoad: function() {
  2. var that = this
  3. douban.fetchComming(that, that.data.start)
  4. },

3、使用地理位置接口动态获取当前城市名称和坐标

原来程序使用硬编码的方式设置当前城市,如下脚本所示

  1. module.exports = {
  2. city: '杭州',
  3. count: 20
  4. }

不过我们不同地方的人员使用的时候,这个城市名称肯定需要变化的,因此可以使用微信的地理位置接口动态获取当前位置信息,然后写入到配置文件里面即可。

  1. //获取当前位置信息
  2. function getLocation (type) {
  3. return new Promise((resolve, reject) => {
  4. wx.getLocation({ type: type, success: resolve, fail: reject })
  5. })
  6. }
  7.  
  8. //根据坐标获取城市名称
  9. function getCityName (latitude = 39.90403, longitude = 116.407526) {
  10. var data = { location: `${latitude},${longitude}`, output: 'json', ak: '6473aa8cbc349933ed841467bf45e46b' };
  11. var url = 'https://api.map.baidu.com/' + 'geocoder/v2/';
  12. var type = 'json';
  13.  
  14. return this.get(url, data, type).then(res => res.result.addressComponent.city);
  15. }

然后我们在app.js里面编写代码,在app启动的时候,动态获取城市名称、坐标信息然后写入配置文件即可,这里使用的还是Promise的函数调用实现。

  1. const utils = require('./comm/script/util.js')
  2. const config = require('./comm/script/config.js')
  3.  
  4. App({
  5. onLaunch: function() {
  6. utils.getLocation()
  7. .then(res=>{
  8. const { latitude, longitude } = res;
  9. config.location = `${longitude},${latitude}`;//当前坐标
  10. console.log(`currentLocation : ${config.location}`);
  11.  
  12. return utils.getCityName(latitude, longitude)
  13. })
  14. .then(name=>{
  15. config.city = name.replace('市', ''); //当前城市名称
  16. console.log(`currentCity : ${config.city}`)
  17. })
  18. .catch(err => {
  19. config.city = '广州'
  20. console.error(err)
  21. })
  22. },
  23. ...

最后呈上改造过代码的运行界面,还是保留原来的功能正常使用。

以上就是我对这个小程序进行不同方面的调整思路和经验总结,希望大家有所收益或者建议,感谢阅读支持。

微信小程序豆瓣电影项目的改造过程经验分享的更多相关文章

  1. 微信小程序——豆瓣电影——(1):基础入门

    准备 Demo 项目地址 https://github.com/zce/weapp-demo Clone or Download(需准备GIT环境) $ cd path/to/project/root ...

  2. 微信小程序——豆瓣电影——(2):小程序运行部署

    Demo 预览 演示视频(流量预警 2.64MB) GitHub Repo 地址 仓库地址:https://github.com/zce/weapp-demo 使用步骤 将仓库克隆到本地: bash ...

  3. 微信小程序 - 豆瓣同城

    代码地址如下:http://www.demodashi.com/demo/12121.html 一.准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/ ...

  4. 微信小程序商城开源项目,Weixin-App-Shop 1.0 版本正式发布!!!

    微信小程序商城开源项目,Weixin-App-Shop 1.0 版本正式发布 Weixin-App-Shop 是捷微团队开发的微信小程序商城开源项目,涵盖了微信商城的全部功能,能够快速发布简单易用的小 ...

  5. 图解微信小程序---获取电影信息

    图解微信小程序---获取电影信息 代码笔记 第一步:编写js文件,调用api获取相对应电影详情信息(注意带入的参数是id不在是榜单的type,电影api的movie后面又斜杠,别忘了,对应的绑定数据的 ...

  6. 图解微信小程序---获取电影列表

    图解微信小程序---获取电影列表 代码笔记 list跳转 第一步:编写前端页面获取相关的电影列表参数(对于显示参数不熟悉,可以先写js,通过console  Log的方式获取我们电影的相关数据字段,后 ...

  7. 微信小程序从零开始开发步骤(四)自定义分享的功能

    上一章节,实现了小程序的底部导航的功能,这一节开始实现一些简单的功能.本章节介绍的是小程序的自定义分享的功能. 可以分享小程序的任何一个页面给好友或群聊.注意是分享给好友或群聊,并没有分享到朋友圈.一 ...

  8. 详解微信小程序开发(项目从零开始)

    一.序 微信小程序,估计大家都不陌生,现在应用场景特别多.今天就系统的介绍一下小程序开发.注意,这里只从项目代码上做解析,不涉及小程序如何申请.打包.发布的东西.(这些跟着微信官方文档的流程走就好). ...

  9. 微信小程序“信用卡还款”项目实践

    小程序概述 11月3日晚,微信团队对外宣布,微信小程序开放公测.开发者可登陆微信公众平台申请,开发完成后可以提交审核,公测期间暂不能发布. 我们前一段时间也进行了小程序开发,现在来对之前的开发体验做一 ...

随机推荐

  1. 【Arduino】使用LCD1602和DHT11制作温湿度显示器

    材料: 1.DHT11 2.LCD1602 3.LCD1602 转接板 4.Arduino UNO 5.Arduino 传感器扩展版 那个Arduino UNO 我当初挑类个便宜的山寨货买,结果发来和 ...

  2. js同时使用多个分隔符分割字符串.

    利用正则分割,str.split(/reg/);如果有这样一个字符串: "jb51.net,google.com,baidu.com_weibo.com_haotu.net", 我 ...

  3. C#的Random到底该怎么使用

    先看代码: 在循环中,有的只NEW一个Random,有的每次都NEW 一个Random. Console.WriteLine("1.多个Random,默认随机种子,"); ; i ...

  4. oracle存储过程统计用户各表记录数

    declare v_tName varchar(50); v_sqlanalyze varchar(500); v_num number; v_sql varchar(500); cursor c1  ...

  5. C#参考之sealed密封类(转)

    C# 语言参考 sealed(C# 参考) 当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承.在下面的示例中,类 B 从类 A 继承,但是任何类都不能从类 B 继承. 1     ...

  6. 【Win 10 应用开发】UI Composition 札记(七):基于表达式的动画

    上一篇烂文中,老周给大伙伴们介绍过了几个比较好玩的动画.本篇咱们深化主题,说一说基于表达式的动画.这名字好理解,就是你可以用公式 / 等式来产生动画的目标值.比如,你想让某个可视化对象的高度减半,你的 ...

  7. Java实现Html转PDF的方法

    写在前面 以下路径问题根据项目结构自己修改,以下是我使用spring boot打成jar包的写法. 一.需求背景 在前端编辑器中输入任意的文本,包括css样式变化,保存为html文本.通过Java后台 ...

  8. 网络分析法(Analytic Network Process,ANP)

    什么是网络分析法 网络分析法(ANP)是美国匹兹堡大学的T.L.Saaty教授于1996年提出的一种适应非独立的递阶层次结构的决策方法,它是在层次分析法(Analytic Hierarchy Proc ...

  9. win下搭建python3+PyQt5+eric6环境

    一.安装python3 1.下载python3的安装包,默认安装即可,注意勾选 Add Python 3.6 to Path .但是这样默认安装的路径太长,不太方便找到,可选择定制安装,自己定义安装路 ...

  10. Qt creator中文输入—fctix-qt5 源码编译 libfcitxplatforminputcontextplugin.so

    fctix-qt5 的源码有两个地方可以下载: wget https://download.fcitx-im.org/fcitx-qt5/fcitx-qt5-1.0.5.tar.xztar -xJf ...