Reputation: 30054
I am building a small notes app and learning Vue3 + Typescript on the way. The code below allows to dynamically create and display an Array of notes (I hope I trimmed it down correctly, a general description is below the code):
<template>
<q-layout>
<div
v-for="note in allNotes"
class="note q-ma-sm q-gutter-sm"
:id="note.id"
>
<q-editor
v-model="note.text"
>
</q-editor>
</div>
<q-page-sticky position="bottom-right" :offset="[18, 18]">
<q-btn fab icon="add" color="accent" @click="addNewNote"/>
</q-page-sticky>
</q-layout>
</template>
<script lang="ts">
import {defineComponent, ref} from 'vue'
export default defineComponent({
name: 'App',
components: {},
setup() {
// a single note
interface Note {
id: number
creationDate: string
text: string
tags: string[]
deleted: boolean
isFocused: boolean
}
// all the notes in the app
let allNotes = ref<Note[]>([])
function addNewNote() {
const now = new Date()
allNotes.value.push({
creationDate: now.toISOString(),
deleted: false,
id: now.getTime(),
tags: [],
text: "",
isFocused: false
})
}
function displayedNotes() {
return allNotes
}
return {
allNotes,
addNewNote,
}
}
});
</script>
<style lang="scss">
</style>
The idea is that allNotes
holds the notes, which are displayed in a v-for
loop.
I wanted to make a small modification, in anticipation that the notes to be displayed will be filtered, to this I created a method displayedNotes
that is supposed to simply return allNotes
(later there will be some filtering happening there)
<template>
<q-layout>
<div
v-for="note in displayedNotes"
class="note q-ma-sm q-gutter-sm"
:id="note.id"
>
<q-editor
v-model="note.text"
>
</q-editor>
</div>
<q-page-sticky position="bottom-right" :offset="[18, 18]">
<q-btn fab icon="add" color="accent" @click="addNewNote"/>
</q-page-sticky>
</q-layout>
</template>
<script lang="ts">
import {defineComponent, ref} from 'vue'
export default defineComponent({
name: 'App',
components: {},
setup() {
// a single note
interface Note {
id: number
creationDate: string
text: string
tags: string[]
deleted: boolean
isFocused: boolean
}
// all the notes in the app
let allNotes = ref<Note[]>([])
function addNewNote() {
const now = new Date()
allNotes.value.push({
creationDate: now.toISOString(),
deleted: false,
id: now.getTime(),
tags: [],
text: "",
isFocused: false
})
}
function displayedNotes() {
return allNotes
}
return {
allNotes,
displayedNotes,
addNewNote,
}
}
});
</script>
<style lang="scss">
</style>
The differences are
v-for
iterates over displayedNotes
and not allNotes
anymoredisplayedNotes()
is a new method.The end result is that nothing is displayed, displayedNotes
is created but is empty when allNotes
grow.
How should I return displayedNotes
so that it is reactive?
Upvotes: 0
Views: 392
Reputation: 491
You should create a computed property like this:
const filteredNotes = computed(() => displayedNotes())
In that case displayedNotes()
might be renamed later on, and in that function you can add your filtering logic. If your allNotes
then changes, that function within computed will be called again and will return the new filteredNotes
What you want to do now is only add filteredNotes
to your return object, and use it in your v-for
loop instead of allNotes
Upvotes: 1