#javascript #html #vue.js #vuejs2
Вопрос:
Я начинающий с Vue и JS, и я изо всех сил пытаюсь обновить атрибут данных экземпляра Vue на основе пользовательского ввода. Это то, что у меня есть в качестве шаблона для компонента Vue (расположенного внутри taskTemplate
переменной):
<div>
<input type="text" placeholder="Insert your task" v-model="desc"/>
<p>{{ desc }}</p>
</div>
Компонент Vue определяется следующим образом:
Vue.component("task-item", {
props: {
id: Number,
desc: String,
},
template: taskTemplate
});
И это заполняется в HTML следующим образом:
<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>
Где список задач создается с помощью экземпляра 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: "" })
}
}
});
Моя проблема в том, что после обновления input
элемента на веб-странице свойство компонента обновляется, но если я введу его в консоль app.taskList[0].desc
, он все равно вернет пустую строку.
Конечная цель состоит в том, чтобы отправить данные, введенные пользователем в вызове API, поэтому, если я смогу получить доступ к компонентам Vue вместо списка задач в свойстве data, все будет в порядке. Я также хотел бы ознакомиться с лучшими практиками здесь.
Комментарии:
1. Вы не должны мутировать реквизит: вы должны были получить предупреждение в консоли вашего браузера. Вместо этого заставьте компонент элемента задачи вносить изменения в родительский элемент, в котором находится источник данных. Смотрите: vuejs.org/v2/guide/components.html#Using-v-model-on-Components
Ответ №1:
Реквизит не следует использовать в двусторонней привязке. Вместо этого свяжите их значение с входными данными и внесите любые изменения в родительский компонент. :value
<div>
<input
type="text"
placeholder="Insert your task"
:value="desc"
@input="$emit('update:desc', $event.target.value)"
/>
<p>{{ desc }}</p>
</div>
В родительском компоненте вам нужно прослушать update
событие и обновить исходное значение:
<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>
Ответ №2:
Попробуйте использовать :value
и @input
вместо 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>