微信小程序状态管理,vuex实战指南
发布时间:10-25来源:微信小程序工具|微信小程序开发|微信小程序制作平台-龙图应用【XcxIP.com】
小程序这玩意儿,看着简单,做着闹心。尤其是状态管理,页面一多,数据一交叉,你就知道什么叫“牵一发动全身”。A页面改了用户信息,B页面还傻乎乎地显示着旧头像;购物车加了两件商品,结算页死活不刷新。这种时候,你就得把vuex请进来了。别看它最初是给Vue网页设计的,在小程序里用好了,那叫一个顺手。

先搞清楚一个核心问题:为什么小程序需要vuex?小程序每个页面都有自己的data,页面之间通信,要么走全局变量,要么走事件总线,要么通过storage。全局变量倒是简单,但改起来没个痕迹,出了bug你连在哪改的都不知道。事件总线在小程序里用起来又别扭,页面销毁了监听还在,内存泄漏防不胜防。storage呢,读写都是异步的,你刚set完立马get,可能拿到的还是旧值。vuex解决了这些痛点:单一数据源,所有状态变化都有迹可循,组件间共享数据不用再绕弯子。
现在说怎么在小程序里装vuex。别去npm装官方vuex,那玩意儿在小程序里跑不顺,得用专门为小程序封装的库,比如“wechat-miniprogram-redux”或者“miniprogram-vuex”。我习惯用后者,它把vuex的API基本原样搬了过来,只是把commit和dispatch的调用方式调整了一下,更贴合小程序的setData机制。安装也简单,npm装完,在app.js里引入,创建一个store实例,然后挂到App上。关键一步是,每个页面里要用一个高阶函数把store里的state和actions映射到页面的data和方法上。
举个例子,你做一个电商小程序,购物车数据肯定得全局共享。在store里定义一个state,叫cartList,数组类型,然后定义mutations,比如ADDTOCART、REMOVEFROMCART、CLEAR_CART。页面里要加购的时候,调用.dispatch('addToCart', product),action里再commit对应的mutation,state更新,所有订阅了这个state的页面自动收到通知,重新计算数据。你看,整个过程数据流向是单向的,出了错,顺着action、mutation、state这条线一查就能定位。
不过,新手容易犯一个错:把什么都塞进vuex。购物车、用户信息、订单状态这些全局共享的,放进去没问题。但有些数据,比如当前页面滚动位置、某个表单的临时输入,这些页面私有的状态,放vuex里就是浪费内存,还会让代码变难维护。vuex的状态树设计有个原则:尽量扁平,不要嵌套太深。你想想,如果state里套了三层对象,每次更新都得用展开运算符一层层复制,写起来累,跑起来也慢。我一般把state拆成模块,user模块管用户信息,cart模块管购物车,order模块管订单,每个模块自己管自己的mutations和actions,互不干扰。
再聊聊getters的妙用。小程序里经常要计算购物车总价,每次在页面里写map或者reduce,又重复又容易出错。在store里定义一个getter,叫cartTotalPrice,把计算逻辑封装好,页面里直接拿结果用。而且getters有缓存机制,依赖的state没变,计算结果不会重新执行,性能上也划算。还有一点,getters可以返回函数,实现带参数的查询,比如根据商品id查购物车里对应的数量,这种场景用getter返回函数特别方便。
还有个坑得提醒你:小程序页面卸载时,store不会自动清理。你如果在一个页面里注册了store的订阅,页面销毁前记得取消订阅,否则会内存泄漏。在onUnload生命周期里,调用.unsubscribe(this.unsubscribe)之类的清理方法。另外,小程序的分包机制会影响store的加载,主包和分包都要引用同一个store实例,别在分包里又new一个,那数据就不通了。解决办法是把store放在公共目录,或者放在主包里,分包里通过getApp()获取全局store。
说说实战中的调试技巧。vuex的状态变化比较隐晦,不像页面data那样直观。我建议在开发环境里,给store加一个plugin,每次mutation触发时,把type和payload打印出来,再打印一下变更后的state,这样就能看到数据流是怎么走的。小程序开发者工具里,也可以在console里手动调用getApp().store.state查看当前状态,排查问题快很多。等线上环境,把这个plugin关掉,免得刷屏。
小程序和vuex搭配,本质是把数据流管起来,让你在复杂业务里还能保持清醒。别觉得引入框架就繁琐,等你维护一个十来个页面的项目,就会明白一套清晰的状态管理能省多少事。从今天起,试着把购物车、用户信息这些全局数据挪进store里,跑通一遍,你会上瘾的。
