微信小程序项目问题优化

1,274 阅读5分钟

情景和联动模式

情景模式是通过把一系列设备控制放在一起,然后触发设备按设定的延迟时间执行,如进入家中手动点击触发回家情景模式,该模式设置了客厅灯打开,亮度、颜色和色温多少,窗帘拉开百分之多少,还可以设置设备的各种控制属性和设备延时执行;联动模式是选择一个主设备的属性触发该模式,相当于时刻监听该主设备的属性变化,一旦设备达到设置条件则触发联动模式,联动可以添加一系列的设备和情景模式,如回家联动模式,主设备设置人体传感器触发则执行联动

其中处理比较复杂的是选中的设备列表数据,其中存储的有设备ID、设备属性以及延时时间(设备列表展示和执行都是根据延时时间来表现)而显示的数据则是设备的名称以及控制属性名字,并且同一设备可以重复添加(所以设备ID 不能做编辑设备属性的唯一标识,每次新增设备时新增一个标识为设备ID 加上在设备列表的索引),相当于给设备添加了定时功能触发。开始处理方式是对设备列表循环获取设备详情在组合一起,不同的属性转化方式会有很大的不同,如颜色,模式,风速类别,所以需要很多的判断来转化成对应的名称。后期的处理优化,通过 map 结构来把情景列表和联动列表来缓存起来,key 为情景或联动标识并且把设备属性选择抽离出组件来实现共用,所以当数据量操作对比很复杂的时候通过 map 结构来缓存数据是一个比较不错的选择

swiper 滑动组件

小程序设备详情展示是通过 swiper 滑动组件展示,每次左右滑动一下更换当前数据,前期是获取该设备类型列表,直接显示所有的 swiper-item 组件,当该设备数量不多时还可以,但当设备(如:灯)过多时会出现滑动卡顿或者卡死的情况,后期的处理优化是进入设备展示时判断该设备类型列表数量大于8时,每次显示三个 swiper-item 或者更换成九宫格展示界面。所以对于有些界面显示方式需要考虑过多或者没有时的展示处理

设备默认值以及状态改变

设备属性展示优化,设备的开关等属性状态默认值以及无法获取值时统一设置为关而不是随意设置。设备控制等判断请求成功后在改变对应界面状态(如开关状态),否则回到改变的初始值(如滑动条)

设备属性递归

当设备列表通过九宫格全部展示在同一界面时,而设备的状态和其它属性又需要通过属性查询接口来获取显示在界面,前期使用 for 循环通过设备ID 遍历来查找对应的设备属性,因为for 循环中为异步操作,所以第一个返回的数据不一定对应设备列表中的第一个,所以又通过设备ID 去对比设备列表所在的索引再进行赋值,后期的处理优化是用递归来取代 for 循环,所以在对循环的顺序要求比较严格而循环的内部又是一个个异步操作的时候,可以考虑使用递归的处理方法,只需要找到递归的终止条件即可(如批量控制设备、批量查询属性等)

icon 字体图标

如开关按钮一系统图标,开始会有大量不同颜色图片,后期优化把许多图片上传到阿里 icon 字体图标库,一方面字体图标大小和颜色控制灵活,另一方面减少了http请求

点击区域

当存在图标点击事件时,点击热点区域尽量增大一点,确保点击的执行成功率(如左上角返回按钮点击)

canvas 和 swiper 滑动偏移

滑动 swiper,定位的 canvas 会出现偏移,将 swiper 标签中的 duration 改成了0,即取消了滑动的渐变效果,canvas 便不再偏移,canvas 使用 wx:if 会在滑动回返时缺少 canvas 线条,应使用 hidden 来代替,

wx:if 在隐藏的时候不渲染,而 hidden 在隐藏时仍然渲染,只是不呈现,注意 canvas 等属性单位为 px

tab 切换

某些 tab 切换是通过点击 tab 栏来达到切换,后期把 tab 栏内容通过 swiper 包裹(scroll-view 组件也可以)来实现左右滑动来切换 tab 内容,但需注意如果内容中也存在滑动事件则会存在冲突

深层次对象值

当使用某个深层次对象时需要判断对象是否存在再进行赋值,不然会出现取不到对象中的值而报错导致后续步骤直接停止

在 wxml 中可以通过逻辑运算&&(如:deviceObj && deviceObj.attrObj && deviceObj.attrObj.power)或 wx:if 来判断整个对象(如:deviceObj.attrObj)或逻辑运算||(如:deviceObj.attrObj.power || ‘--’)
在js中可以通过封装公共函数来判断,如:
let objProp = (data, path) => {  
    if (!data || !path) {    return null  }  
    let tempArr = path.split('.');  
    for (let i = 0; i < tempArr.length; i++) {    
        let key = tempArr[i];    
        if (data[key]) {      
            data = data[key];    
        } else {      
            return null;    
        }  
    }  
    return data;
}
let data = { deviceObj: { attrObj: { power: 'on' } } }
console.log(objProp(data, 'deviceObj.attrObj.power'))    //on
console.log(objProp(data, 'deviceObj.propObj'))    //null
console.log(objProp(data, 'deviceObj.attrObj.wind'))    //null

浮动按钮

浮动按钮中有对设备名称,区域更改以及设备解绑,放置在右下角,但因为不同页面浮动按钮放置位置可能会遮挡部分操作内容,所以在不同页面它的 bottom 不同,但是还是不够灵活,后期使浮动按钮在竖直一定范围内进行拖拽,开始考虑过使用小程序 movable-view 自带组件,但是必须放在一定区域 movable-area 中,但 movable-area 又会遮挡页面内容的操作,所以还是通过 catchtouchmove 事件来进行拖拽