0

I am new to using Vue3 (composition API) with bootstrap 5 and came across a problem:

When I render a list, and pass each element as a prop as so:

<div :key="item.id" v-for="item in items">
   <EditItem :item="item"/>
</div>

I can modify the props values just fine inside of EditItem.vue (the props are JSON objects), but when I am inside a modal I can only modify the values for the 1st index. My code looks something like this:

<script setup>
   defineProps({
      item: {
         type: Object, 
         required: true
      },
   })
</script>

<template>

<!-- Let's me edit all items in list just fine -->
<input type='text' v-model="item.name">
<div> {{item.name}} </div>


<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
  Edit Item
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="mb-3">

           <!-- Will only let me edit the first indexed list item -->
           <label for="name" class="form-label">Item name</label>
           <input type='text' class="form-control" id="name" placeholder="John Doe" v-model="item.name">
           <div> {{ item.name }} </div>

        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
</template>

I think this happens due to the modal being treated as a different document/context so vue3 re-renders everything, so the indexing restarts from 1. I am not sure how to fix this issue, any help is appreciated. Thanks

Edit:

My problem is similar to the issue described in this question: How to show fresh bootstrap modal data when using Vue.js

However, it hasn't been answered properly and is from 2018

Edit 2:

Solved: It was a simple fix, simply take the modal out of the v-for loop. Only have the button inside the loop. And yes, I realize you cannot edit the values of a prop inside of a child component. I simplified the code, as the code with the form I have is quite long due to the many fields in my JSON objects.

1 Answer 1

0

Props are readonly. To be able to edit array, you need to emit delete function where you have this array. Your "Lets me edit all items" not working too. It just edits a local variable, not an array.

This is how you make reusable form:

form.vue

<template>
    <form @submit.prevent="$emit('onSubmit', data)">
        <input type="text" v-model="data.name" />
        <button type="submit">Save</button>
    </form>
</template>

<script setup>
const props = defineProps({ item: { type: Object, required: true }})
const data = reactive(props.item)
defineEmits(['onSubmit'])
</script>

parent.vue

<template>
   <form :item="item" @on-submit="editItem"></form>
</template>

<script setup>

function editItem(data) {
   // Edit array here.
}
</stript>
Sign up to request clarification or add additional context in comments.

1 Comment

Yes sorry, I actually do have a form. I just simplified the code as it was quite long and forgot about the 1-way data flow prop property. Anyways that was not my issue, it was something much simpler. Nonetheless, thank you for the help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.