小程序项目开发有感

1,692 阅读5分钟

引言

经历了9月紧张的小程序新项目的开发后,总觉得应该沉淀一下,记录一下遇到的问题和一些开发过程中遇到的坑。

杂记

setData

这是一个小程序中非常常用的操作,熟悉react的话,可以把这个函数理解为是react的setState,这个函数触发了小程序页面的重新渲染。 setData文档链接

这次的实际开发中就遇到了一些性能上的问题,总结起来就是不要在setData里更新较大的数据不要频繁使用setData。这个问题一般来源于列表。

解决方案

  • 不要在Data中存放一些复杂对象,比如Moment对象
  • 列表一定要注意分页,保证每次setData的数据不要过大
  • 合并不必要的setData操作

页面渲染层级

一般在web开发中,我们都会用opcity或者zindex等来控制渲染的层级。在小程序中需要注意原生组件的渲染层级是会高于webview中的渲染内容的层级中,这就需要开发者统筹的考虑modal,tabbar,navigation这些组件的渲染和遮挡的问题。必要时,需要考虑使用cover-view这种原生的组件去实现一些弹层。

input

原生组件的限制

小程序的input是一个特殊的组件,这个组件实际是由一个非focus状态的普通组件,和一个focus状态的原生组件构成的。

本次实际开发中发现这个组件在被受控时,安卓,ios及模拟器上的表现并不完全一致。比如在受控的value值直接变化的时候,在安卓上会触发input的事件,模拟器上则没有。这种情况是非常出现兼容性不一致的缺陷的。

微信sdk api的版本

这个在开发过程中建议前期定一个sdk的的版本,在开发工具中设定即可,这样开发中即使使用了不可使用的api,也可以及时在开发过程中发现,避免后期暴露带来的兼容的风险

微信api的promise化

微信基础提供的api都是利用回调的方式去实现异步的回调,这里以request为例。

wx.request({
  url: 'test.php', //仅为示例,并非真实的接口地址
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success (res) {
    console.log(res.data)
  },
  fail (err) {
    console.log(err)
  },
})

可以看到相对来说写法比较难受,所以可以统一的对wx对象下的api进行promise化。

export const wxPromisify = (api) => {
    return function (obj = {}, ...args) {
        return new Promise((resolve, reject) => {
            const ops = Object.assign({}, obj, {
                success: (res) => {
                    obj.success && obj.success(res);
                    resolve(res);
                },
                fail: (err) => {
                    obj.fail && obj.fail(err);
                    reject(err);
                }
            });
            wx[api](ops, ...args);
        });
    };
};

如果我需要一个promiseRequest那么只要

const promiseRequest = wxPromisify('request');
promiseRequest({url: xxx}).then(res => {
    console.log(res)
})

就变得很好用了。核心代码也很容易,其实就是让函数执行后返回一个promise对象,并且把resolve和reject对应的放到success和fail方法中,兼容了原本在opt中传入的success和fail方法,也支持resolve和reject。这里除了可以实现promise化,如果代码需要一些api使用的监控或者日志,同样可以在success和fail方法中统一增加对应的代码,完成对所有wx api的业务封装。

wxs

这个没有什么可说的,比较麻烦的就是wxs支持的基础对象的api很少,如果直接要迁移js,会有很多兼容性问题,直接使用js的库,更会产生不小的风险。

自定义组件

在实际开发中一定会遇到要抽象一些公共组件或者是业务组件的场景。微信小程序的自定义组件的开发和vue很像。需要注意的是微信的事件很努力的去接近了web开发中的事件,但是还是在事件上有自己的特殊性。

比如composed属性,事件是否可以穿越组件边界,为false时,事件将只能在引用组件的节点树上触发,不进入其他任何组件内部。

这个可以认为是限定了事件冒泡的范围。

另外小程序的组件的生命周期也相对很怪异,没有update这类生命周期,需要监听属性变化就只能使用observers去做一些事情。而observers和behaviors这两个很好用的东西竟然只能使用在组件上,这一点限制也说明了在实现层面上微信的组件和页面完完完全全的不一致。

其他

微信小程序项目的打包构建,持续交付也都是一个在项目开发中比较特殊的存在,这块可能需要单独去深挖了,实现上相对复杂了。

总结

业务项目的快速交付中,已完成任务为第一要务,技术点上很多时候都是一知半解的去理解了,微信小程序很容易会当成是黑盒去开发。 但其实在微信的文档上其实很明确的说明了,这就是一个hybrid技术,渲染与计算的分离,微信api其实就是一堆hybrid sdk能力的聚合,这些api最后都是落在了微信的原生能力上,比如请求,比如扫码拍照。 目前的学习方式除了官方文档和网上博客的推测式的说法外,就是去与其他的hybrid技术方案做比较了。