美文网首页
vue3中获取proxy原始对象的问题

vue3中获取proxy原始对象的问题

作者: AaronZ_dd7f | 来源:发表于2020-11-25 20:03 被阅读0次

    项目中遇到如下问题

    1. 在usePassengers先将数组arr通过ref响应式化
     // 用户的数据
     const data = [
        { id: 1, name: 'a' },
        { id: 2, name: 'b' },
        { id: 3, name: 'c' },
        { id: 4, name: 'd' }
      ]
    // 此处做响应化
    const passengers = ref(data)
    
    1. 在组件中,需要用到passengers的数据作为复选框的值,部分代码如下
    const passengersChecked = ref(new Set(unref(passengers)))
    
    1. 在页面操作后,用户提交,开始组装报文
    const passengersCheckedValue = toRaw(unref(passengersChecked))
    
    1. 发现passengersCheckedValue<Set>里面都是响应式对象
    console.log(passengersCheckedValue) // Set(4) {Proxy, Proxy, Proxy, Proxy}
    

    原因

    1. Set 构造函数 会访问数组Symbol(Symbol.iterator)、length属性和每一个key,只要访问了就会触发代理的get陷阱,get陷阱会对访问到的值继续做响应化处理
    get陷阱会对访问到的属性的值继续响应化
    1. 生成的Set中的子元素就是响应化后的对象,而不再原来的Object。既Set(4) {Proxy, Proxy, Proxy, Proxy}

    2. 然后在对Set(4) {Proxy, Proxy, Proxy, Proxy}进行响应式化。此时的target就是Set(4) {Proxy, Proxy, Proxy, Proxy}

    3. toRaw 只是返回响应式对象的ReactiveFlags.RAW(__v_raw)属性,为target。

    源码中的toRaw

    解决方案

      // 1. 在生成Set的时候就获取去响应化后的值
      const passengersChecked = ref(new Set(toRaw(unref(passengers))))
      // 2. 使用shallowRef,只跟踪自己的 .value 更改,但不会使其值成为响应式的。
      const passengers = shallowRef(data)
    

    如下的这些操作也会造成对数组属性的访问,从而触发代理的get陷阱

    const passengersChecked = [...passengers]
    // 同 new Set(passengers)
    // 属性访问顺序 Symbol(Symbol.iterator) length 0 length 1 length 2 length 3
    
    const passengersChecked = Object.entries(passengers)
    // 属性访问顺序 0 1 2 3
    
    const passengersChecked = Object.values(passengers)
    // 属性访问顺序 0 1 2 3
    

    相关文章

      网友评论

          本文标题:vue3中获取proxy原始对象的问题

          本文链接:https://www.haomeiwen.com/subject/aeaniktx.html