I am attempting to learn Vue for the first time and I am building an application where I have a section where there are rows of data. Each row will be associated with lots of data about that element, to avoid loading all this data at one I have previously implemented a sort of “expandable row” using the v-show attribute. This was working great that on button press the row of information would expand and a call to my database would be made to retrieve the extra information about that specific row would be retrieved.
This was working until I attempted to add button that open modals for editing the information associated with that row or confirming deletion of that row. I was following the example on the Vue examples page about how to make a modal to get started (this example).
To hopefully explain this better I have the following structure to my components:
Row.vue
-> RowContent.vue
-> -> DeleteModal.vue
-> -> EditModal.vue
Row: The always visible information for each row including the button that will expand the row to make the RowContent visible
RowContent: The information that will be visible once the button is pressed in Row.vue and will contain the buttons to make the DeleteModal.vue and EditModal.vue visible.
DeleteModal.vue: The modal that will appear to ask the user if they are sure they want to delete the row
EditModal.vue: The modal that will appear so the user can edit the information in the row
Here is my code for the RowContent.vue and Row.vue:
Row.vue:
<script setup>
const isOpen=ref(false);
function expand(npc) {
isOpen.value = !isOpen.value
npcName.value = ref(npc.get('Name'));
if(isOpen.value){
getClass(npc);
getType(npc);
getRace(npc);
}
}
</script>
<template>
<div class="RowBackground">
<div class="alwaysShown">
<h1>{{ npc.get('Name') }}</h1>
<button @click="expand(npc)">Expand</button>
</div>
<RowContent class='drawer' :npcName='npcName' :npcClass='npcClass' :npcType='npcType' :race='race' :extra='extra' v-show='isOpen'></RowContent>
</div>
</template>
<script>
import RowContent from './RowContent.vue';
export default {
props: {
npc: Object,
},
components: {
RowContent,
},
</script>
RowContent:
<script setup>
import DeleteModal from '../components/DeleteModal.vue';
import { ref } from 'vue';
const showModal= ref(false);
</script>
<template>
<div class="rowContainer">
<div class="row">
<h3>Class: {{ npcClass }}</h3>
<h3>Type: {{ npcType }}</h3>
</div>
<div class="row">
<h3>Race: {{ race }}</h3>
<h3>Extra: {{ extra }}</h3>
</div>
<div class="row">
<button class="editButton">Edit</button>
<button class="deleteButton" @click="showModal=true">Delete</button>
</div>
</div>
<DeleteModal :npcName="npcName" :show="showModal" @close="showModal = false">
</DeleteModal>
</template>
DeleteModal:
<script setup>
const props = defineProps({
show: Boolean,
});
</script>
<template>
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<h3 class="deleteText">Delete {{ npcName }} permanently?</h3>
</div>
<div class="modal-body">
<div class="interactionButtons">
<button>Confirm</button>
<button @click="$emit('close')">Cancel</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
npcName: {
type: String
}
},
data() {
return {
isOpen: false,
};
},
}
</script>
I left out some of the styling and functions that are connecting to my backend because I did not think they were applicable. Please leave a comment and let me know if these will help in diagnosing the problem.