Vue.js2 - Object.assign ({}, this.var), предотвращающий метод наблюдения - PullRequest
0 голосов
/ 31 мая 2018

возвращение this.user (глобальное вычисляемое свойство) работает как положено.Конечно, я делаю копию, потому что я не хочу перезаписывать реальные данные пользователя.Итак, я использую Object.assign.Однако, как только я включаю return Object.assign ({}, this.user) (в отличие от this.user), метод watch больше не работает.

Вот мой шаблон (я использую bootstrap-vue):

<template>
  <form role="form">
    <b-form-group
      label="First Name"
      label-for="basicName"
      :label-cols="3"
      :horizontal="true">
        <b-form-input id="user-name-first" type="text" v-model="userFormData.fname"></b-form-input>
    </b-form-group>
          <b-form-group
      label="Last Name"
      label-for="basicName"
      :label-cols="3"
      :horizontal="true">
        <b-form-input id="user-name-lirst" type="text" v-model="userFormData.lname"></b-form-input>
    </b-form-group>
          <b-form-group
      label="Email"
      label-for="user-email"
      :label-cols="3"
      :horizontal="true">
        <b-form-input id="user-email" type="text" v-model="userFormData.email"></b-form-input>
    </b-form-group>
      <b-form-group
          :label-cols="3"
          :horizontal="true">
                    <b-button type="submit" variant="primary">Save changes</b-button>
            <b-button type="button" variant="secondary" @click="userFormCancel">Cancel</b-button>
        </b-form-group>
      </form>
</template>

Итак, это работает и устанавливает editsPending в true всякий раз, когда изменения применяются к userProfile (через v-модель навход)

<script>
export default {
  name: 'userProfile',
  data () {
    return {
      editsPending: false
    }
  },
  computed: {
    userFormData: function () {
      return this.user
    }
  },
  watch: {
    userFormData: {
      deep: true,
      handler (val) {
        this.editsPending = true
      }
    }
  },
  methods: {
    userFormCancel () {
      this.editsPending = false
    }
  }
}
</script>

... но это не так; userFormData становится клоном user , но editsPending не зависит от обновлений userFormData .

<script>
export default {
  name: 'userProfile',
  data () {
    return {
      editsPending: false
    }
  },
  computed: {
    userFormData: function () {
      return Object.assign({}, this.user)
    }
  },
  watch: {
    userFormData: {
      deep: true,
      handler (val) {
        this.editsPending = true
      }
    }
  },
  methods: {
    userFormCancel () {
      this.editsPending = false
    }
  }
}
</script>

Может кто-нибудь объяснить, почему это может происходить, и предложить жизнеспособное решение?

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Вычисляемое свойство будет переоцениваться только после изменения некоторых его зависимостей.( source )

Вот почему он работает с return this.user, а не с Object.assign, потому что это не реактивная зависимость.

Если вам нужны реактивные данныеВы должны инициализировать userFormData как пустые данные объекта и назначить своего пользователя при создании вашего экземпляра Vue:

  data () {
    return {
      editsPending: false,
      userFormData: {}
    }
  },
  created() {
    this.userFormData = Object.assign({}, this.user)
  },
0 голосов
/ 31 мая 2018

Проверены разные вещи для воспроизведения поведения, которое вы видите.

Я подозреваю, что в вашем шаблоне вы привязываете свои входные данные к UserFormdata (неверно)

<input v-model="userFormData.name">

Вместо (правильно)

<input v-model="user.name">

Если бы вы могли поделиться своим шаблоном, который бы помог;)

Редактировать: после добавления шаблона.

new Vue({
  el: '#app',
  data () {
    return {
      editsPending: false,
      user: { name: 'John Doe' },
      userCachedData: {},
    }
  },
  created() {
    this.userCachedData = Object.assign({}, this.user);
  },
  watch: {
    user: {
      deep: true,
      handler (val) {
        this.editsPending = true
      }
    }
  },
  methods: {
    userFormCancel () {
      this.editsPending = false
    }
  }
})

<div id="app">
  {{ user }}
  {{ userCachedData }}
  <br>
  <input v-model="user.name" />
  {{ this.editsPending }}
</div>

Codepen: https://codepen.io/aurelien-bottazini/pen/BVNJaG?editors=1010

...