Reputation: 884
I have Parent/child component and bind arrays of object by proxy and without proxy:
const selectedTags = ref([]);
const tags = [
{
id: 'efrwe',
},
{
id: 'dhjhe23',
}];
<Child :tags="tags" :selectedTags="selectedTags">
In child component i add selected element from 'tags' to 'selectedTags', its reference to object from source array!
props.selectedTags.push(tags[0]);
But then i try compare this reference on same object i return false!
console.log(tags[0] == selectedTags[0]); // false
You say "okey you try compare proxy object and clear object" but i try comapare with target of proxy and return false again!
console.log(tags[0] == selectedTags[0].target); // false
console.log(tags[0] == selectedTags.target[0]); // false
i try also with 'value'
console.log(tags[0] == selectedTags[0].value); // false
console.log(tags[0] == selectedTags.value[0]); // false
how can i compare reference of same object in vue 3 ?
I think you understand that i want do, computed that return non selected items:
let nonSelected = computed(() =>
props.tags.filter(t => props.selectedTags.every(s => s != t))
);
Upvotes: 1
Views: 6106
Reputation: 222864
The problem is that tags
is regular non-reactive array, and selectedTags
is deeply reactive, tags[0]
is regular object, and selectedTags.value[0]
is reactive object, i.e. Proxy
instance.
In order to discard a proxy, initial object could be retrieved with toRaw
:
toRaw(tags[0]) === toRaw(selectedTags.value[0]).id
ref
is unnecessary here because it's not reassigned, it could be reactive array.
But the main problem is that the reactivity of tags
and selectedTags
is mismatched without a reason. They should either be defined as deeply reactive arrays, e.g. (readonly
or reactive
), or both as shallowly reactive arrays (shallowReactive
, or a combination of reactive
and markRaw
).
Generally there wouldn't be such problem because this approach doesn't work well with immutable objects that can be expected to be used in such places. A way to do this is to discard object equality and compare the objects by a property that identifies them, i.e. id
:
tags[0].id === selectedTags[0].id
Optional chaining can be used if necessary.
As it was said, it's a bad practice to mutate a prop; this makes data flow more complicated. Instead, a child needs to emit selectedTags
or a list of id
to a parent.
Upvotes: 6