So I am building a search page in Vue 3 using the composition API. I have a component which takes a set of data from the parent and shows a snippet of the data including where the keyword is, and so it needs to make a working copy of this data to make a displayable value.
I had a lot of weird errors because I was initially using the following code, thinking it would just get the value:
setup(props) { const displayEntry = ref(props.entry) ...
but this ended up being reactive and changing the original data. I don’t need the reactivity because I create the component dynamically from the parent. I also don’t want to keep a working copy of the data in the parent because that will increase code complexity. I then tried a myriad of different solutions to try to break the reactivity until I got to simply:
displayEntry.value = props.entry
At which point my linter goes bananas…
error Getting a value from the `props` in root scope of `setup()` will cause the value to lose reactivity vue/no-setup-props-destructure
So what is the correct way to just get the value from a prop?
Advertisement
Answer
Turns out that I was somehow passing a reference in the parent. Following is my code:
setup(props) { watchEffect(() => { if (searchTerm.value == "") { filteredEntries.value = [] } else { filteredEntries.value = entries.value.filter(searchFilter) } }) return { searchTerm, filteredEntries, echo, showPreview } }
And in the template:
<SearchPreview v-for="( entry, index ) in filteredEntries" :key="index" :entry="entry" :search-term="searchTerm" />
No clue why it passes a ref and I’m not sure how to just pass the value, but I fixed it in the component with the following hack:
const displayEntry = ref(JSON.parse(JSON.stringify(props.entry)))
(this leaves some nested properties undefined but I pass those separately to make it work)