I'm making a dynamic table using Vue 3 as a learning project, in which the user can add or remove rows from the table, among other things. I'm using a table-row
component to create the row, and a table-data
component to create data cells within that row. Adding a row is done via the following code:
const app = Vue.createApp({
data() {
return {
tableRows: [],
}
},
methods: {
addRow() {
this.tableRows.push(-1);
},
},
})
What I need to do is to pass the array TableRows
and index
to the table-row
component, in order to perform a row delete operation, as shown in this code:
app.component('table-row', {
props: {
tableRows: Array,
index: Number,
},
methods: {
deleteRow(index) {
this.tableRows.splice(index, 1);
}
},
template: `
<tr>
<table-data></table-data>
<table-data></table-data>
<table-data></table-data>
<table-data></table-data>
<button @click="deleteRow">Delete Row</button>
</tr>
`
})
The issue is that both the values of TableRows
and index
are undefined (as seen in the Vue DevTools), which means the props are not being passed from the parent to the child component. I think that's the reason why this error pops up whenever I click the Delete Row button:
Uncaught TypeError: Cannot read properties of undefined (reading 'splice')
Here's a screenshot from Vue DevTools. You can see that the props variables have undefined values:
I'm not really sure why is this happening, or what I can do to remedy this. Any help is greatly appreciated.
CodePudding user response:
I think all props must first be declared in the parent's data before they're bound as props in children
"PARENT"
<template>
...
<Child :tableRows="tableRows" />
...
</template>
...
<script>
...
data() {
return {
tableRows: []
}
}
...
</script>
"CHILD"
...
</script>
...
props: {
tableRows: Array
}
...
</script>
As for index, you will likely have to emit
the event back up to the parent on click.
"CHILD"
<template>
...
<button @click="$emit('deleteRow')">Delete Row</button>
...
</template>
Here you'd have to deal with it in the parent, where e is the value associated with the event--in this case, presumably the index you want.
"PARENT"
<template>
...
<Child @deleteRow="deleteRow(e)" :tableRows="tableRows" />
...
</template>
CodePudding user response:
You didn't pass index
in @click="deleteRow"
Try to change method to :
deleteRow() {
this.tableRows.splice(this.index, 1);
}
or pass index
to method:
@click="deleteRow(index)"