Vue 3 使用代理包装器比较对相同对象的引用

Vue 3 compare references to same objects with proxy wrapper

我有 Parent/child 组件并通过代理和不使用代理绑定对象数组:

const selectedTags = ref([]);
const tags = [
    {
        id: 'efrwe',
    },
    {
        id: 'dhjhe23',
    }];

<Child :tags="tags" :selectedTags="selectedTags">

在子组件中,我将所选元素从 'tags' 添加到 'selectedTags',它对源数组中对象 的引用!

props.selectedTags.push(tags[0]);

但后来我尝试在同一对象上比较此引用 return false!

console.log(tags[0] == selectedTags[0]); // false

你说“好吧,你尝试比较代理对象和清除对象”,但我尝试比较代理对象和 return false!

console.log(tags[0] == selectedTags[0].target); // false
console.log(tags[0] == selectedTags.target[0]); // false

我也尝试 'value'

console.log(tags[0] == selectedTags[0].value); // false
console.log(tags[0] == selectedTags.value[0]); // false

我如何比较 vue 3 中相同对象的引用?

我想你明白我想做的,计算出 return 个未选择的项目:

let nonSelected =  computed(() =>
     props.tags.filter(t => props.selectedTags.every(s => s != t))
);

问题是tags是正则non-reactive数组,selectedTags是深度反应,tags[0]是正则object,selectedTags.value[0] 是反应性的 object,即 Proxy 实例。

为了丢弃代理,可以使用 toRaw:

检索初始 object
toRaw(tags[0]) === toRaw(selectedTags.value[0]).id

ref在这里是不必要的,因为它没有被重新分配,它可能是反应数组。

但主要问题是 tagsselectedTags 的反应性无缘无故地不匹配。它们应该被定义为深度反应阵列,例如(readonlyreactive),或两者都作为浅反应数组(shallowReactive,或 reactivemarkRaw 的组合)。

一般不会有这样的问题,因为这种方法不能很好地处理不可变的 objects,可以预期在这些地方使用。一种方法是丢弃 object 相等性,并将 object 与标识它们的 属性 进行比较,即 id:

tags[0].id === selectedTags[0].id

必要时可以使用可选链接。

如前所述,改变 prop 是一种不好的做法;这使得数据流更加复杂。相反,child 需要发出 selectedTagsid 列表到 parent.