I'm new to Vue and trying to display a list of "notes" which update when a button is hit (I've just hardcoded the value to add for now). The trouble is that after I add a new item to the array, this isn't updated in the UI. I'm using Vue3 and The :key I'm using is unique. Other "widgets" I've made have worked as expected but they got data from an api response. Is it related maybe to the async/await aspect of dealing with API responses compared with just appending/pushing to the data array?
<template>
<Widget class="notes" :style="style" @load="showNotes()">
<h3>Notes</h3>
<p v-for="item in data" :key="item.id">{{ item.note }}</p>
<button @click="addNote()">Add</button>
</Widget>
</template>
<script>
import Widget from "./Widget.vue";
export default {
name: "Notes",
props: {
widgetWidth: Number,
},
computed: {
style() {
return "max-width: " + this.widgetWidth + "px";
},
},
data() {
return {
notes: undefined,
};
},
methods: {
addNote() {
var x;
if (!this.data) {
this.data = [];
x = 0;
} else {
x = this.data.length;
console.log(x);
}
this.data.push({ id: x, note: "another" });
console.log(this.data);
},
showNotes() {
this.data = [{ id: 0, note: "init" }];
},
},
beforeMount() {
this.showNotes();
},
components: { Widget },
};
</script>
<style scoped>
.notes {
min-width: 100px;
word-wrap: break-word;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.notes > * {
flex-grow: 1;
}
</style>
Create a computed property called notes that returns the notes property in your data object. In your v-for use item in notes. When you click the button the notes in your data object gets updated. The computed property detects the change and updates the ui
That's happening because you modify the data property and there is no data property, it's notes property, Also, you don't need the @load event, or beforeMount event to initialize the notes property.