@Dmi3ii

Как отключить реактивность в компоненте?

Есть компонент (форма редактирования) в нее летит объект (массив). При создании я хочу объект сохранить и отслеживать изменения полей (computed isChanged). При изменении item.department меняется и item_loaded.department. Подскажите как отключить реактивность? Через $options не получилось. Есть задумка попробовать через Vuex, но кажется есть способ проще...

<template>
  <div>
    <h3 class="headline">Редактор</h3>
    <code>({{item_loaded.department}}={{item.department}})</code> //реактивно. всегда равно
    <h3 v-show="isChanged">(изменение)</h3>

    <v-autocomplete
        :items    = "app.departments"
        v-model = "item.department"
        label   = "Отдел"
    />

    <v-btn @click="save()" color="info">
        <v-icon left>fa-save</v-icon>Сохранить
    </v-btn>
  </div>
</template>

<script>
export default {
  props: {
      item: {
          type    : Object,
          default : null
      },
  },

  data() {
    return {
        item_loaded : null
    }
  },

  created() {
    this.item_loaded = this.item
  },

  computed: {
    isChanged() {
      if (this.item_loaded.department == this.item.department) {
        return false
      } else {
        return true
      }
    }
  },
}
</script>
  • Вопрос задан
  • 1627 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
При изменении item.department меняется и item_loaded.department

this.item_loaded = this.item

Реактивность, как же. Язык не знаете, а лезете фреймворками пользоваться. Правильно будет так (погуглите, в чём разница между примитивными типами данных и объектами):

this.item_loaded = { ...this.item }

Не очень понятно, зачем created - в data контекстом является экземпляр компонента, параметры доступны, так что копировать объект можно прямо там:

data() {
  return {
    item_loaded: { ...this.item },
  };
},

Вычисляемое свойство isChanged - можно же сделать в одну строку вместо пяти:

isChanged() {
  return this.item_loaded.department !== this.item.department;
},

Почему в качестве дефолтного значения для item используется null? - вы обращаетесь к его свойствам, если ничего не передать, получится ошибка cannot read property of null. Должен быть объект:

default: () => ({ /* можно указать какие-нибудь свойства с дефолтными значениями */ }),

Мутируете параметр (v-model="item.department"). Правильно будет эмитить изменения в родительский компонент и обновлять объект уже там. В родителе цепляете значение для параметра item с модификатором sync, а в рассматриваемом компоненте v-model заменяете на установку значения и обработку события input:

<input
  :value="item.department"
  @input="$emit('update:item', { ...item, department: $event.target.value })"
>
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы