欢乐马 2024-11-06 11:59 采纳率: 66.7%
浏览 6
已结题

同步两个不同结果的array中某些属性

需求:实际项目中我想把一个array或者对象中某一些属性提取出来做出一个新的array。虽然是新旧array的结果不一样但是希望让这些属性修改的时能够让新旧array同步更新。

测试代码:事例中只能单向同步,实际操作还存在有的时候双休不能同步。按上面的需求一般的通用做法是怎样子的呢谢谢

<template>
    <view>
        <view style="color: aquamarine;" @click="click_a">点击测试a</view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                array1: [
                    {
                        category: "饮料",
                        product: {
                            title: "豆浆",
                            num: 12
                        }
                    },
                    {
                        title: "豆浆",
                        num: 3,
                    },
                    {
                        title: "豆浆",
                        num: 5,
                    },
                    {
                        title: "馒头",
                        num: 6,
                    },
                    {
                        title: "豆浆",
                        num: 1,
                    }
                ],
                array2:[]
            };
        },
        methods: {
          click_a() {
            this.array2.push(this.array1[0].product)
            console.log("array2 is:", this.array2);
            this.array1[0].product.num = 100
            console.log("array1 is:", this.array1);
            console.log("array2 is:", this.array2);        
            this.array1.num = 200
            console.log("array1 is:", this.array1);
            console.log("array2 is:", this.array2);
          }
        }
    }
</script>

<style lang="scss">

</style>


  • 写回答

14条回答 默认 最新

  • 杨同学* 2024-11-06 12:52
    关注

    该回答引用ChatGPT4o, 并由本人整理回复, 如有帮助,还请采纳。
    在你的需求中,你希望通过同步不同数组或对象中的某些属性实现双向绑定。也就是说,修改 array1 中某些属性时,array2 中相对应的属性也会自动更新,反之亦然。

    JavaScript 原生的数据结构如对象和数组并不直接支持双向绑定,因此你需要一些技巧或特定的实现方式来实现同步效果。以下是一些通用的做法:

    方法 1:使用 Proxy 实现双向绑定

    Proxy 是一种高级方式,可以拦截对象的操作。你可以使用它来创建一个代理对象,这样一旦其中的属性发生变化,其他数组或对象也会同步更新。

    export default {
      data() {
        const array1 = [
          {
            category: "饮料",
            product: {
              title: "豆浆",
              num: 12
            }
          },
          {
            title: "豆浆",
            num: 3,
          },
          {
            title: "豆浆",
            num: 5,
          },
          {
            title: "馒头",
            num: 6,
          },
          {
            title: "豆浆",
            num: 1,
          }
        ];
    
        const array2 = [];
    
        // 用 Proxy 包装 array1 的 product 对象,实现双向绑定
        const proxyArray1 = array1.map(item => {
          if (item.product) {
            item.product = new Proxy(item.product, {
              set(target, key, value) {
                target[key] = value;
    
                // 同步更新 array2
                const index = array2.findIndex(p => p.title === target.title);
                if (index !== -1) {
                  array2[index][key] = value;
                }
    
                return true;
              }
            });
          }
          return item;
        });
    
        return {
          array1: proxyArray1,
          array2: array2
        };
      },
      methods: {
        click_a() {
          // 初始化 array2 并与 array1 的 product 属性同步
          this.array2.push(...this.array1.map(item => item.product).filter(Boolean));
    
          // 修改 array1 中的 product.num
          this.array1[0].product.num = 100;
    
          // 验证同步效果
          console.log("array1 is:", this.array1);
          console.log("array2 is:", this.array2);
        }
      }
    };
    

    在这个例子中,我们使用 Proxy 包装了 array1 中的 product 对象,这样每次修改 product 中的属性时,都会同步更新到 array2 中对应的对象。

    方法 2:使用 Object.defineProperty 手动实现监听

    Proxy 出现之前,常用的是 Object.defineProperty 来实现数据同步。虽然有些繁琐,但可以用于一些简单的需求。

    export default {
      data() {
        const array1 = [
          {
            category: "饮料",
            product: {
              title: "豆浆",
              num: 12
            }
          },
          {
            title: "豆浆",
            num: 3,
          },
          {
            title: "豆浆",
            num: 5,
          },
          {
            title: "馒头",
            num: 6,
          },
          {
            title: "豆浆",
            num: 1,
          }
        ];
    
        const array2 = [];
    
        // 使用 Object.defineProperty 进行监听和同步
        array1.forEach(item => {
          if (item.product) {
            array2.push(item.product);
    
            Object.keys(item.product).forEach(key => {
              let value = item.product[key];
              Object.defineProperty(item.product, key, {
                get() {
                  return value;
                },
                set(newValue) {
                  value = newValue;
                  // 同步 array2 中对应的对象
                  array2[array2.indexOf(item.product)][key] = newValue;
                }
              });
            });
          }
        });
    
        return {
          array1,
          array2
        };
      },
      methods: {
        click_a() {
          // 修改 array1 中的 product.num
          this.array1[0].product.num = 100;
    
          // 验证同步效果
          console.log("array1 is:", this.array1);
          console.log("array2 is:", this.array2);
        }
      }
    };
    

    这里通过 Object.defineProperty,可以监听 product 的每个属性,当属性被修改时,会自动同步到 array2 中的对应属性。

    方法 3:使用 Vue 的响应式系统

    如果你在 Vue 项目中,可以利用 Vue 的响应式系统。虽然 Vue 的响应式系统并不直接支持双向绑定,但可以通过计算属性和 watch 实现一些效果。以下是一个简单的示例:

    export default {
      data() {
        return {
          array1: [
            {
              category: "饮料",
              product: {
                title: "豆浆",
                num: 12
              }
            },
            {
              title: "豆浆",
              num: 3,
            },
            {
              title: "豆浆",
              num: 5,
            },
            {
              title: "馒头",
              num: 6,
            },
            {
              title: "豆浆",
              num: 1,
            }
          ],
          array2: []
        };
      },
      computed: {
        syncedArray2() {
          // 基于 array1 创建 array2 并保持同步
          return this.array1.map(item => item.product).filter(Boolean);
        }
      },
      watch: {
        array1: {
          handler(newVal) {
            // 当 array1 改变时,重新赋值给 array2
            this.array2 = newVal.map(item => item.product).filter(Boolean);
          },
          deep: true,
          immediate: true
        },
        array2: {
          handler(newVal) {
            // 双向同步 array2 中的变化到 array1
            newVal.forEach((product, index) => {
              if (this.array1[index] && this.array1[index].product) {
                this.array1[index].product.num = product.num;
              }
            });
          },
          deep: true
        }
      },
      methods: {
        click_a() {
          // 修改 array1 中的 product.num
          this.array1[0].product.num = 100;
    
          // 验证同步效果
          console.log("array1 is:", this.array1);
          console.log("array2 is:", this.array2);
        }
      }
    };
    

    这里通过 computedwatch 的组合,尝试在 Vue 中保持 array1array2 的双向同步。这种方式在 Vue 的响应式系统下表现良好。

    总结

    • 使用 Proxy 是一种更现代、灵活的方式,适合复杂的双向同步需求。
    • Object.defineProperty 适合在简单场景下使用,但不如 Proxy 灵活。
    • 在 Vue 中,通过 computedwatch 实现同步,充分利用 Vue 的响应式系统。

    你可以根据需求选择适合的方式来实现双向同步。希望这些方法对你有所帮助!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(13条)

报告相同问题?

问题事件

  • 系统已结题 11月14日
  • 已采纳回答 11月6日
  • 创建了问题 11月6日

悬赏问题

  • ¥15 centos7中sudo命令无法使用
  • ¥15 灰狼算法和蚁群算法如何结合
  • ¥15 这是一个利用ESP32自带按键和LED控制的录像代码,编译过程出现问题,请解决并且指出错误,指导如何处理 ,协助完成代码并上传代码
  • ¥20 stm32f103,hal库 hal_usart_receive函数接收不到数据。
  • ¥20 求结果和代码,sas利用OPTEX程序和D-efficiency生成正交集
  • ¥50 求fpga交通信号灯设计Verilog代码
  • ¥50 adb连接不到手机是怎么回事?
  • ¥20 抓取数据时发生错误: get_mooncake_data() missing 1 required positional argument: 'driver'的问题,怎么改出正确的爬虫代码?
  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联