Vue.js2 - Object.assign({},this.var)阻止监视方法

时间:2018-05-31 19:50:17

标签: javascript vuejs2 bootstrap-vue

返回this.user(全局计算属性)按预期工作。当然,我正在制作副本,因为我不想覆盖实际的用户数据。所以,我正在使用Object.assign。但是,一旦我包含返回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>

因此,无论何时将更改应用于 userProfile (通过输入上的v-model),此功能都会将 editsPending 设置为 true

<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 会成为用户的克隆,但 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>

任何人都可以解释为什么会发生这种情况并提出可行的解决方案吗?

3 个答案:

答案 0 :(得分:1)

  

计算属性只会在某些时候重新计算   依赖关系已经改变。 (source

这就是为什么它适用于return this.user而不是Object.assign,因为它不是一个被动的依赖。

如果您需要反应数据,则应将userFormData初始化为空对象数据,并在创建Vue实例时为您的用户分配:

  data () {
    return {
      editsPending: false,
      userFormData: {}
    }
  },
  created() {
    this.userFormData = Object.assign({}, this.user)
  },

答案 1 :(得分:0)

测试不同的内容以重现您看到的行为。

我怀疑您的模板中的输入绑定到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

答案 2 :(得分:0)

您可以使用$ emit为对象分配值:

mounted() {
  this.$emit("userFormData", this.user);
}