Полный цикл в digital

Реактивность компонентов в Vue

С компонентами можно работать реактивно, давайте разберемся на примерах:

Реактивное удаление компонентов

Давайте научимся реактивно удалять дочерние компоненты из списка. Сделаем для этого в каждом дочернем компоненте специальную кнопку. По нажатию на эту кнопку будет испускаться событие и в родительском компоненте будет удаляться заданный дочерний компонент по его id.

Пусть в родительском компоненте дан следующий массив объектов:

App.vuedata()
{
    return {
        users: [
            {
                id: 1,
                name: 'name1',
                surn: 'surn1'
            },
            {
                id: 2,
                name: 'name2',
                surn: 'surn2'
            },
            {
                id: 3,
                name: 'name3',
                surn: 'surn3'
            },
        ],
    }
}

Напишем в родительском компоненте метод удаления юзера по его id:

App.vuemethods: {
    remove(id)
    {
        this.users = this.users.filter((user) => {
            return user.id !== id;
        })
    }
}

Создадим компоненты в цикле, передав им параметром имя, фамилию, idи метод для удаления:

App.vue<template>
    <User
        v-for   ="user in users"

        :id     ="user.id"
        :name   ="user.name"
        :surn   ="user.surn"
        @remove ="remove"
        :key    ="user.id"
    />
</template>

Пропишем входящие данные в настройке props и испускаемое событие в настройке emits:

components/User.vueprops: {
    id:     Number,
    name:   String,
    surn:   String,
},
emits: ['remove'],

Выведем в представлении компонента имя и фамилию юзера:

components/User.vue<template>
    {{ name }}
    {{ surn }}
</template>

А теперь сделаем кнопку, по нажатию на которую будет испускаться событие для удаления. Параметром этого события будет передаваться id компонента. Родительский компонент при получении события удалит данного юзера из массива объектов и он реактивно исчезнет из списка юзеров:

components/User.vue<template>
    {{ name }}
    {{ surn }}

    <button @click="$emit('remove', id)">
        remove
    </button>
</template>

Готовый код

App.vue<script>
import User from './components/User.vue'
export default {
  data()
  {
    return {
      users: [
        {
          id: 1,
          name: 'name1',
          surn: 'surn1'
        },
        {
          id: 2,
          name: 'name2',
          surn: 'surn2'
        },
        {
          id: 3,
          name: 'name3',
          surn: 'surn3'
        },
      ],
    }
  },
  methods: {
    remove(id)
    {
      this.users = this.users.filter((user) => {
        return user.id !== id;
      })
    }
  },
  components: {
    User
  }
}
</script>
<template>
  <User
      v-for   ="user in users"
      :id     ="user.id"
      :name   ="user.name"
      :surn   ="user.surn"
      @remove ="remove"
      :key    ="user.id"
  />
</template>
components/User.vue<script>
export default {
  props: {
    id:     Number,
    name:   String,
    surn:   String,
  },
  emits: ['remove'],
}
</script>
<template>
  {{ name }}
  {{ surn }}
  <button @click="$emit('remove', id)">
    remove
  </button>
</template>

Реактивное редактирование данных компонента

Давайте теперь реализуем редактирование данных наших дочерних компонентов. Для начала в родительском компоненте сделаем метод изменения юзера по его id:

App.vuemethods: {
    change(id, name, surn)
    {
        this.users = this.users.map((user) => {
            if (user.id === id) {
                user.name = name;
                user.surn = surn;
            }
            return user;
        });
    }
}

Создадим компоненты в цикле, передав им параметром имя, фамилию, id и метод для изменения:

App.vue<template>
    <User
        v-for   ="user in users"

        :id     ="user.id"
        :name   ="user.name"
        :surn   ="user.surn"
        :key    ="user.id"
        @change="change"
    />
</template>

Пропишем испускаемое событие в настройке emits дочернего компонента:

components/User.vueprops: {
    id:     Number,
    name:   String,
    surn:   String,
},
emits: ['change'],

Теперь в дочернем компоненте сделаем свойство, которое будет задавать режим компонента, показ или редактирование:

components/User.vuedata()
{
    return {
        isEdit: false,
    }
}

Сделаем также свойства для поддержки работы инпутов для редактирования:

components/User.vuedata()
{
    return {
        isEdit: false,
        newName: '',
        newSurn: '',
    }
}

Сделаем так, чтобы начальные значения этих свойств брались из пропсов:

components/User.vuedata()
{
    return {
        isEdit: false,
        newName: this.name,
        newSurn: this.surn,
    }
}

Сделаем метод, который будет запускать режим редактирования:

components/User.vuemethods: {
    edit()
    {
        this.isEdit = true;
    }
}

Сделаем метод, который будет сохранять отредактированные данные, отключая при этом режим редактирования:

components/User.vuemethods: {
    save()
    {
        this.isEdit = false;
        this.$emit('change', this.id, this.newName, this.newSurn);
    }
}

Сделаем представление дочернего компонента:

components/User.vue<template>
    <template v-if="!isEdit">
        {{ name }}
        {{ surn }}
        <button @click="edit">
            edit
        </button>
    </template>
    <template v-else>
        <input v-model="newName">
        <input v-model="newSurn">
        <button @click="save">
            save
        </button>
    </template>
</template>

Готовый код

App.vue<script>
import User from './components/User.vue'
export default {
  data()
  {
    return {
      users: [
        {
          id: 1,
          name: 'name1',
          surn: 'surn1'
        },
        {
          id: 2,
          name: 'name2',
          surn: 'surn2'
        },
        {
          id: 3,
          name: 'name3',
          surn: 'surn3'
        },
      ],
    }
  },
  methods: {
    change(id, name, surn)
    {
      this.users = this.users.map((user) => {
        if (user.id === id) {
          user.name = name;
          user.surn = surn;
        }
        return user;
      });
    }
  },
  components: {
    User
  }
}
</script>
<template>
  <User
      v-for   ="user in users"
      :id     ="user.id"
      :name   ="user.name"
      :surn   ="user.surn"
      :key    ="user.id"
      @change="change"
  />
</template>
components/User.vue<script>
export default {
  data()
  {
    return {
      isEdit: false,
      newName: this.name,
      newSurn: this.surn,
    }
  },
  props: {
    id:     Number,
    name:   String,
    surn:   String,
  },
  emits: ['change'],
  methods: {
    edit()
    {
      this.isEdit = true;
    },
    save()
    {
      this.isEdit = false;
      this.$emit('change', this.id, this.newName, this.newSurn);
    }
  }
}
</script>
<template>
  <template v-if="!isEdit">
    {{ name }}
    {{ surn }}
    <button @click="edit">
      edit
    </button>
  </template>
  <template v-else>
    <input v-model="newName">
    <input v-model="newSurn">
    <button @click="save">
      save
    </button>
  </template>
</template>
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!