Tengo una aplicación Vue 3. En esta aplicación, necesito mostrar una lista de elementos y permitir que un usuario elija elementos en la matriz. Actualmente, mi componente se ve así:
MiComponente.vue
<template> <div> <div v-for="(item, index) in getItems()" :key="`item-${itemIndex}`"> <div class="form-check"> <input class="form-check-input" :id="`checkbox-${itemIndex}`" v-model="item.selected" /> <label class="form-check-label" :for="`checkbox-${itemIndex}`">{{ item.name }} (selected: {{ item.selected }})</label> </div> </div> <button class="btn" @click="generateItems">Generate Items</button> </div> </template> <script> import { reactive } from 'vue'; export default { data() { return itemCount: 0 }, methods: { generateItems() { this.itemCount = Math.floor(Math.random() * 25) + 1; }, getItems() { let items = reactive([]); for (let i=0; i<this.itemCount; i++) { items.push({ id: (i+1), selected: false, name: `Item #${i+1}` }); } return items; } } } </script>Cuando hago clic en seleccionar/deseleccionar la casilla de verificación, el texto "seleccionado" no se actualiza. Esto me dice que no me he vinculado a la propiedad correctamente. Sin embargo, tampoco estoy seguro de lo que estoy haciendo mal.
¿Cómo vinculo una casilla de verificación a la propiedad de un objeto en una matriz en Vue 3?
Si establece un punto de interrupción en getItems() , o emite un archivo console.log allí, notará que cada vez que cambia la selección de una casilla de verificación, se le llama. Esto se debe a que el bucle v-for se vuelve a representar y llamará a getItems() , que le devolverá una nueva lista de elementos con el restablecimiento selected a false en todo. El que estaba antes ya no lo usa nada.
Para solucionar esto, solo podría llamar a getItems() desde generateItems() por ejemplo, y almacenar esa matriz en algún lugar, como en data , y cambiar el v-for para iterar eso en lugar de llamar al método getItems() .
Steve tiene razón.
Aquí hay una versión fija: Vue SFC Playground .
<template> <div> <div v-for="(item, index) in items" :key="`item-${index}`"> <div class="form-check"> <input type="checkbox" class="form-check-input" :id="`checkbox-${index}`" v-model="item.selected" /> <label class="form-check-label" :for="`checkbox-${index}`">{{ item.name }} (selected: {{ item.selected }})</label> </div> </div> <button class="btn" @click="generateItems">Generate Items</button> </div> </template> <script> import { reactive } from 'vue'; export default { data() { return { items: [] } }, methods: { generateItems() { this.itemCount = Math.floor(Math.random() * 25) + 1; this.getRndItems(); }, getRndItems() { this.items = reactive([]); for (let i=0; i<this.itemCount; i++) { this.items.push({ id: (i+1), selected: false, name: `Item #${i+1}` }); } } } } </script>