【学习】微信小程序开发中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
            });
        }
    }
});
posted @ 2024-05-18 23:53  小拳头呀  阅读(55)  评论(0编辑  收藏  举报