как изменить значение других братьев и сестер на in vue?

#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:

Я бы не рекомендовал вам изменять значение другого брата, поскольку вы не можете быть уверены в побочных эффектах, которые это может вызвать, очевидно, что когда вы смотрите на список задач, может показаться, что побочных эффектов нет, но в общей практике узел должен изменять элементы, которые находятся под нимв родительском происхождении ни выше, ни у братьев и сестер.

Если вы хотите изменить элементы выше, они всегда управляются через события. Вы сообщаете родителю, что что-то нужно изменить, а не меняете это самостоятельно.

Это то, что вы можете сделать здесь:

  1. Вместо использования editable в качестве свойства данных, используйте его как опору для компонента TodoListItem.
     props: {
      editable: {
        type: Boolean,
        default: false
      },
    }
  
  1. При нажатии кнопки Сохранения / редактирования в дочернем компоненте вместо изменения самого значения используйте события, подобные 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);
  
  1. Как только это событие будет выдано, в родительском 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, значение родительского компонента изменится, но новый разработчик никогда не поймет, что происходит и почему.