#javascript #vue.js
#javascript #vue.js
Вопрос:
Играем вслух с vue со списком задач.
На этом этапе я могу отобразить список внутри и с помощью кнопки редактирования текст будет вводом, чтобы я мог редактировать элементы задач. Но, например, если у меня есть 10 элементов, и я нажал редактировать для элемента 2 и элемента 4 и элемента 5, то все эти 3 элемента будут преобразованы во входные данные.
Я думаю, что если я нажму на пункт 4, пункт 2 снова изменится на текст, поэтому при нажатии на редактирование будет отображаться только один элемент ввода.
У меня есть код шаблона, как показано ниже
<td class="col-8">
<!-- if editable is false, show the checkbox and todo item -->
<div class="custom-control custom-checkbox" v-if="!editable">
{{ todo.item }}
</div>
<!-- if editable is true, turn item into an input so user can enter new value -->
<div v-else>
<input ref="editItem" type="text" class="form-control" :value="todo.item" @input="onInput">
</div>
</td>
<td class="col-2">
<button
class="btn btn-sm"
:class="editable ? 'btn-outline-success' : 'btn-outline-info'"
@click.prevent="editable ? onSave() : onEdit()">{{ editable ? 'save' : 'edit' }}
</button>
</td>
Когда я открываю проверку vue в Chrome, я вижу, что все элементы имеют разные значения данных.
Как я могу изменить значение других братьев и сестер?
Заранее спасибо за любые предложения и советы.
Ответ №1:
Я бы не рекомендовал вам изменять значение другого брата, поскольку вы не можете быть уверены в побочных эффектах, которые это может вызвать, очевидно, что когда вы смотрите на список задач, может показаться, что побочных эффектов нет, но в общей практике узел должен изменять элементы, которые находятся под нимв родительском происхождении ни выше, ни у братьев и сестер.
Если вы хотите изменить элементы выше, они всегда управляются через события. Вы сообщаете родителю, что что-то нужно изменить, а не меняете это самостоятельно.
Это то, что вы можете сделать здесь:
- Вместо использования
editable
в качестве свойства данных, используйте его как опору для компонента TodoListItem.
props: {
editable: {
type: Boolean,
default: false
},
}
- При нажатии кнопки Сохранения / редактирования в дочернем компоненте вместо изменения самого значения используйте события, подобные so.
/** You should keep a deepCopy of the props if you are changing the state
of that object and then send the updated local data prop to the parent
as well for updation rather than changing the prop object.
NEVER CHANGE THE PROP OBJECT DIRECTLY. -> this.todoItem =
this.deepCopy(this.todo);
Do this in before mount hook of the child component.
**/
this.$emit('todo-item-action', action, todoItem);
- Как только это событие будет выдано, в родительском
TodoList
компоненте перехватите это событие и измените состояние элементов следующим образом:
<todo-list-item
v-for="todo in todos"
:key="todo['id']"
:todo="todo"
:editable="todo['editable']"
@todo-item-action="handleItemAction"
>
или, если вы не хотите изменять объект todo. здесь вы можете убедиться, null
что editableItem равен, если не выбрано значение none или указан только идентификатор активного элемента, так что prop изменится, и автоматически другой элемент списка станет недоступным для редактирования.
<todo-list-item
v-for="todo in todos"
:key="todo['id']"
:todo="todo"
:editable="editableItem === todo['id']"
@todo-item-action="handleItemAction"
>
Чем больше вы управляете компонентом с помощью событий и реквизитов, тем более пригодным для повторного использования он становится. Всегда имейте компонент orchestrator, который управляет этими stateless
компонентами, обрабатывая события, распространяемые ими, и отправляя состояние через props.
Это подход, которому я всегда следовал, и он всегда позволял мне проводить чистый и быстрый рефакторинг.
С уважением.
Комментарии:
1. таким образом, в основном говорится, что родительский элемент получает управление, дочерний список при нажатии переходит
edit
$emit
к родительскому элементу и используетid
элемент сравнения со списком при рендеринге в родительском элементе, который затем передаетeditable
реквизиты дочернему элементу2. Я согласен, по умолчанию путь является реквизитом и используется в качестве вашего механизма связи для перемещения данных вверх и вниз по компонентам. Если это становится слишком громоздким, т. Е. Приходится выполнять детализацию по нескольким дочерним компонентам или передавать данные через несколько родительских компонентов, именно здесь вы обычно видите рекомендации по переходу к модулю управления состоянием, такому как Vuex.
3. @MikeWright полностью понимает, есть ли слои, которые нужно пройти, просто еще не очень разбирался в vuex и очень хочет составить этот список задач, чтобы использовать vuex как можно скорее в процессе обучения. Но я бы предположил, что, хотя в данный момент я не прохожу несколько слоев вверх и вниз, все равно было бы лучше использовать vuex, чтобы прохождение через слои не требовалось?
4. сохранение deepCopy реквизита вместо его прямого изменения означало бы что-то вроде, если бы я отредактировал свой
onSave
метод значения элемента, который вызывает api для редактирования, но после успешного выполнения запроса я не должен делать что-то вродеthis.todo.item = newItemValue
, а вместо$emit
этого для родительского элемента, где находятся все мои данные списка элементов?5. @Dora Да, изменение значения prop всегда приводит к неожиданному поведению. Значение в родительском компоненте изменяется по ссылке без ведома родителя, поэтому допустим, вы добавили промежуточное событие в родительский компонент, который не знает, что ожидаемое значение было изменено, это привело бы к нежелательным результатам. Более того, этот подход с явной установкой значения в родительском элементе более удобочитаем, иначе, если вы измените значение prop, значение родительского компонента изменится, но новый разработчик никогда не поймет, что происходит и почему.