小程序项目框架搭建

2018-01-21  本文已影响1126人  这是一只喵
随着小程序越来越火,我们也迎来了新任务 —— 微信小程序。

项目开发前,框架的搭建是很必要的,好的项目框架结构清晰,使用方便,开发高效,且利于维护。吃过框架红利的我对此体验颇深,刚接触我司iOS项目的时候,明显感觉不是一个人写的,项目的整体框架清晰,基础的网络模块,存储模块都进行了合理封装,View层架构也都有规范的布局,刚接触项目小白的我,熟悉起来也很容易。But在看各个子页面的功能代码时,很多都不能直视,完全不是一个水准的东西。尽管子界面代码差些,但有总框架的支撑,维护起来还是很顺手的。搭了一个强健的骨架,包装差些,但轻易还是垮不掉的,反过来就不好说了。

项目要开始了,前端工程师提供了一套框架,里面还有基础的网络请求封装和WEUI基础组件库,基于npm三方管理。东西挺全,通用框架,不过我感觉可以二次封装下,更适用于我们的项目,因此开始了此次的 css 、JavaScript 、html 小白的探坑之旅。

我司小程序为app的翻版,沿用app的api 及 开发模式,所以我比较清楚要什么。

一.全局的字体颜色规范
由于最后需要根据不同的院线,打出不同的包,所有全局颜色的配置就很必要了,都不一样嘛。 同理,设计想修改项目中的字号,不能一个一个去项目里改啊,最好设成全局变量。

这个对于小白来说还是需要思考下的,小程序中没有宏,不能像其它语言中那么干。

(1) 可以用数据绑定的方式,在HTML中绑定控件css 属性的字号和颜色,由 js 层控制,不过总感觉这么写起来太low了,还影响到了 js 和 html 层的结构,下下策。

(2)写多套css ,通过动态改变 class 来变换不同的颜色字号, 恩,强那么一点点,还是low.

(3)经过查资料及尝试,发现第三种方式(tip)在css 可以通过 --name:value 语法定义变量的,且小程序 主界面控件都含在 page 中,so 全局变量出现了,写在文件config.wxss中。只放个小例子:

  page {
        --color-a:red;
        --color-b:yellow;
        --color-c:blue;
  }

app.wxss 中引用

@import 'config/config.wxss';

其它子wxss中使用

.title {
      text-align: center;
      color: var(--color-a);
}
.button {
      margin: auto;
      width: 40%;
      height: 200rpx;
      background-color:var(--color-b);
}

这就是我的最终方案了,遗憾的是 var(--color-b) 写起来慢了点。 注意:该配置不包含 nav 及 tabbar 的颜色,需要去 app.json 中手动修改(后期写脚本)

二. 网络层的封装
因为小程序沿用app的api ,url 参数可分为公用参数和每个接口的特有参数,及接口签名。不能每次请求全手打一遍吧,又累出错率又高,所以决定重新封个网络层出来。
要封网络层,项目中网络请求的相关代码需要弄懂,探之旅正式开始。
1.网络请求主文件 wxRequest.js
##主要代码

function wxPromisify(fn) {
    return function (obj = {}) {
      return new Promise((resolve, reject) => {
        obj.success = function (res) {
          //成功
        resolve(res)
        }
        obj.fail = function (res) {
          //失败
        reject(res)
        }
        fn(obj)
      })
    }
  }

get调用方法

 function getRequest(url, data) {
    var getRequest = wxPromisify(wx.request)
    return getRequest({
        url: url,
        method: 'GET',
        data: data,
        header: {
            'Content-Type': 'application/json'
        }
    })
 }

对于几乎js零基础的小白来说,这段代码太不友好了,这都什么玩意!
()=>{} function (obj={}){} where the res , what is Promise , 三层返回,各种闭包,那是怎么请求的? 反正我看懂这都都已经眼疲劳了。
wxPromisify 传入函数名,返回一个包装Premise的函数 ,Premise监听异步函数fn,当外部调用getRequest时,执行返回包裹这Premise的函数,异步请求fn(obj)开始执行。 obj 是啥? 是啥啊 {} 空,加个success 和 fail , 各种尝试后,神经大条的打印了下obj,看到了解释,如果obj为空,且外层函数的第一个参数不为空的话,则obj = 第一个参数,妹的,秀操作!!!
另外付promise的传送门,里面有70%的用法吧,漏掉的不是很多,对应上wxPromisify还是够用的。

网络层的调用原理懂了,那么开始二次封装吧。
首先是网络连接,在每次网络调用的时候写
url=http:/group.leying.com/app/init?cinema_id=101....
low爆了有没有,对此封装了url路径管理文件url.js

  var host = "http://group.leying.com"
  /**
   * 自营后台 所有连接的路径
   */ 
  var urlPath = {
        movieList:  host + "/movie/movie-online-list?",
        init:       host + "/app/init?"
  }
  module.exports = {
        urlPath : urlPath, 
  }

通过引入 url.js就能用key获取到url路径了。
路径的问题解决了,下面解决参数的问题。参数分为公用参数和每个接口的特有参数,公用和特有的合并,去重,进行签名,也封装在url.js

// 公共参数   
var publicParameter = {
    group   :   '***',           // ***
    ver     :   '5.2.2',         // 小程序版本
    city_id :   '499',           // 选择城市id 没有为“”
    cinema_id:  '101',           // 选择影院id 没有为“”
    session_id: '',              // 用户session,没有为“”
    ****  ,                     // ***
} 
var urlParameter = function(parameter) {
      // 1.传入的部分 与 公用参数部分 合并
      extentObj(parameter,publicParameter)
      // 2.细节 参数需要从新排序
      parameter = sortObj(parameter)
      // 3.进行签名
      parameter['.sig'] = getSig(parameter)
      // 返回
      return parameter
}

// 对象合并的方法 用于 公用参数与特有参数的合并(附带去重功能)
    var extentObj = function (obj1, obj2) {
    for (let key in obj2) {
          if (obj2.hasOwnProperty(key) && (!obj1.hasOwnProperty(key))) {
    obj1[key] = obj2[key]
            }
        }
    }
 sortObj = function (obj) {
      var newkey = Object.keys(obj).sort();
      var newObj = {};
      for (var i = 0; i < newkey.length; i++) {
      newObj[newkey[i]] = obj[newkey[i]];
      }
      return newObj
}

就贴这几个方法记录下吧。较坑的是签名的地方,知道签名key,知道签名方式,且在签名正确的情况下给我报了N个签名错误。左右反复核对,没发现问题,和和app发出的比对发现了个特色点,连接的参数居然是按字母顺序排序的。要给objc的属性从排序,厉害了,试了半天的sort()无果后,退而求其次。请求成功了,爽酸 ~ 也解了我长久的疑惑,捕获url,把里面的参数换位进行请求,局然成功,后台是怎么比对签名的那。 终于了解了 ~ 从排序的问题你知道么? 太佩服破我们签名的人了,我知道key和格式都破了一下午, 他们真是 666 啦 ~

最终请求优化版:
app.js中引入url.js,同时增加 urlService 对象

  var urls = require('config/url.js');
  var wxRequest = require('util/wxRequest');
  var wxApi = require('util/wxApi');

  App({
      urlService : {
                // 网络相关
                urls: urls.urlPath,     // 所有的自营 urls
                urlParameter: urls.urlParameter,  // 自营参数加密相关处理
                wxRequest: wxRequest,   // 调用微信外部链接 封装
                wxApi: wxApi            // 调用微信内部链接 封装
      }
  })

因app()对象为全局,在各页面js中请求就容易了index.js请求为例

    Page({
        downLoad: function() {
        var url = getApp().urlService.urls.init
        var parameter = getApp().urlService.urlParameter({
            promotion_type : '1',    // 我是特有参数
            cineme_id : '1111'        // 我是特有参数
        })
       getApp().urlService.wxRequest.getRequest(url, parameter)
      .then(this.downSuccess)
      .catch((res)=>{
        // console.log(res)
      })
    },
    downSuccess (res) {
        // console.log(res);
    }
  })

请求的封装完成,没有污染wxRequest.js文件,时间主要花在思考封装和学习js上。本计划在wxRequest.js文件里处理相应数据的,只有errcode不为0,就触发reject,考虑到微信外部请求不光是发向自家后台,格式不同,决定在.then中在加一层数据处理。时间关系,先用这个框架半成品。

负责iOS很长时间了,也看过后台的项目结构,稍微有些项目结构的概念。后期框架计划增加 logic文件夹处理个别逻辑负责的界面,比如选座,确认订单。model文件夹,处理响应数据多的接口返回的数据,几个大接口各分一个响应的js文件进行数据处理。service文件夹,如果有需要,考虑放出来一个。至于界面的view层结构,先探坑,有时间在说。缓存方面,用微信提供的就好啦 ~

呐 ~ 晨会每次都是在看小程序框架、框架、框架 ~ 这就是了 ,刷了很多基础刷出来的。

收获 : Promise 的使用肯定的,css 自定义属性,还有几个没放出来的css 小 tip. 刷了 css、css3 的基础,轮了wxml 的基础组件库,又有机会和设计制定规范了,原来css里的px和设计标的px是两个东西 , 原来MVVM框架核心优势还有数据绑定。趟了js 的几个小坑 ()=>{} , res=>{} , function(obj={}) ,objc 属性排序 ... 吧啦吧啦

上一篇下一篇

猜你喜欢

热点阅读