Soy un principiante con Vue y JS y estoy luchando para actualizar el atributo de datos de la instancia de Vue según la entrada del usuario. Esto es lo que tengo como plantilla para el componente Vue (ubicado dentro de la variable taskTemplate ):
<div> <input type="text" placeholder="Insert your task" v-model="desc"/> <p>{{ desc }}</p> </div>El componente Vue se define de la siguiente manera:
Vue.component("task-item", { props: { id: Number, desc: String, }, template: taskTemplate });Y esto se rellena en el HTML de la siguiente manera:
<div id="task-list"> <task-item v-for="item in taskList" v-bind="item" ></task-item> <div id="add-more"> <button v-on:click="newTask" type="button">Add a new task</button> </div> </div>Donde se crea la lista de tareas con la instancia de Vue:
var app = new Vue({ el: "#task-list", data: { taskList: [ { id: 1, desc: "" }, { id: 2, desc: "" }, ] }, methods: { newTask() { this.taskList.push({ id: this.taskList.length + 1, desc: "" }) } } }); Mi problema es que después de actualizar el elemento de input en la página web, la propiedad del componente se actualiza, pero si escribo en la consola app.taskList[0].desc , aún devuelve una cadena vacía.
El objetivo final es enviar los datos que el usuario ha introducido en una llamada API, por lo que si puedo acceder a los componentes de Vue en lugar de a la lista de tareas dentro de la propiedad de datos, todavía está bien. Me gustaría saber las mejores prácticas aquí también.
Los accesorios no deben usarse en un enlace bidireccional. En su lugar, vincule su valor a input :value y emita cualquier cambio en el componente principal.
<div> <input type="text" placeholder="Insert your task" :value="desc" @input="$emit('update:desc', $event.target.value)" /> <p>{{ desc }}</p> </div> En el componente principal, debe escuchar el evento de update y actualizar el valor de origen:
<div id="task-list"> <task-item v-for="item in taskList" :key="item.id" // do not forget about key v-bind="item" @update:desc="item.desc = $event" // or you can use the sync modifier to listen to update events for all item's props. // v-bind.sync="item" ></task-item> <div id="add-more"> <button v-on:click="newTask" type="button">Add a new task</button> </div> </div>Intente usar :value y @input en lugar v-model :
Vue.component('task-item', { template: ` <div> <input type="text" placeholder="Insert your task" :value="desc" @input="$emit('update', $event.target.value)"/> <p>{{ desc }}</p> </div> `, props: { id: Number, desc: String, }, //template: taskTemplate }) new Vue({ el: '#demo', data: { taskList: [ { id: 1, desc: "" }, { id: 2, desc: "" }, ] }, methods: { newTask() { this.taskList.push({ id: this.taskList.length + 1, desc: "" }) } } }) <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="demo"> <div id="task-list"> <task-item v-for="(item, index) in taskList" :key="index" v-bind="item" @update="item.desc = $event" ></task-item> <div id="add-more"> <button v-on:click="newTask" type="button">Add a new task</button> </div> </div> </div>