【学习】微信小程序开发中setData不生效
前言
在微信小程序开发中,使用了vantui的步进器显示购物车中商品数目:
现在希望步进器到0时,弹框提示是否删除该物品,确定即删除,取消则步进器回到1。不成想,setData设置为1无论如何都不生效。
wx.showModal({
title: '确认移除',
content: '您确定要移除这件物品吗?',
success: (res) => {
if (res.confirm) {
console.log('用户点击确定')
// 处理删除逻辑
...
} else if (res.cancel) {
console.log(index)
// 处理取消逻辑
...
this.setData({
[`data[${index}].num`]: 1
)};
}
}
});
排查
1)起初怀疑是wx.showModal
导致的:
showModal
本身是异步函数,弹窗时后续的setData
可能将这里覆盖掉了,但是将后面的setData移除后,这里仍旧无法置成1。
2)后来怀疑是vantui本身的bug:
步进器这里在wxml中使用遍历生成的,怀疑是setData
没有影响到wxml中的实际变量,因此创建了一个Button,增加一个test函数手动setData
,发现点击按钮后可以成功设置。也排除了vantui的问题。
真相
最后发现,当用户点击取消操作后,setData
设置为1意外的数字是生效的:
this.setData({
[`data[${index}].num`]: 2
);
恍然大悟。
为了优化性能,setData
的设计非常注重最小化数据传输和视图更新。每次调用 setData
时,只有发生变化的数据才会被处理和传输到视图层,然后触发视图更新。这种差异化更新减少了不必要的 DOM 操作,从而提高了应用的性能。
也就是说,vantui的步进器在从1变成0这个过程中,由于渲染任务执行的先后顺序,前端页面上虽然已经变成了0,但是setData记录的数据仍旧是1,此时将其设置为1,就会认为该数据没有变化,导致设置未生效。
解决
解决方法很简单,可以在设置前,将其修改为其他值,再修改为目标值。
wx.showModal({
title: '确认移除',
content: '您确定要移除这件物品吗?',
success: (res) => {
if (res.confirm) {
console.log('用户点击确定')
// 处理删除逻辑
...
} else if (res.cancel) {
console.log(index)
// 处理取消逻辑
...
this.setData({
[`data[${index}].num`]: -1
});
this.setData({
[`data[${index}].num`]: 1
});
}
}
});