Vue.js为什么我的观察者无法正常工作?

时间:2018-07-11 07:29:09

标签: vue.js vuetify.js

在输入数据上设置观察者之后,我试图同时显示旧值和新值,但是它们都未定义...可能出什么问题了?

请参阅codepen.io

HTML

<div id="app">
  <v-app id="inspire">
    <v-container mt-1 grid-list-xl">
      <v-layout row wrap justify-space-around>
        <v-flex d-flex sm6 md6>
          <v-layout row wrap>
            <v-flex d-flex>
              <v-card class="flexcard" dark tile flat>
                <v-card-title class="card__title justify-center">PROFILE</v-card-title>
                <form @submit.prevent="onUpdateProfile()">
                <v-card-text class="card__text grow">
                  <v-text-field  @keyup.native="setDirty" placeholder="Enter your new email address" :readonly="isReadOnly" label="Email" v-model="user.email" prepend-icon="email">
                  </v-text-field>
                </v-card-text>
                <v-card-actions>
                  <v-tooltip  v-if="isReadOnly" right>
                      <v-btn  @click="onEditProfile" icon class="primary" large slot="activator">
                       <v-icon color="white">edit</v-icon>
                        </v-btn>
                        <span>EDIT</span>
                  </v-tooltip>                                                                                          
                <v-btn v-if="isProfileEditing" round @click="cancel()">CANCEL</v-btn>
                <v-btn v-if="isProfileDirty" round color="primary" type="submit">UPDATE</v-btn>
                </v-card-action>
                </form>
              </v-card>
            </v-flex>
          </v-layout>
        </v-flex>
     </v-layout>
      </v-container>
  </v-app>
</div>

JS

new Vue({
  el: '#app',
  mounted () {
    this.user.email = 'john.doe@example.com'
  },
  data: () => ({
     user: {
      email: ''
    },
    cache: {
      user: {
        email: ''
      }
    },
    editIcon: {
      email: 'edit'
    },
    isProfileEditing: false,
    isProfileDirty: false,
    isReadOnly: true
  }),
  watch: {
    user: function (newUser, oldUser) {
      console.log('Old User Email: ', oldUser.email)
      console.log('New User Email: ', newUser.email)
    }
  },
  computed: {
  },
  methods: {
    onUpdateProfile () {
      console.log('UPDATE PROFILE: ', this.user.emaill)
    },
    onEditProfile () {
      this.isProfileEditing = true
      this.isReadOnly = false
      this.cache.user.email = this.user.email
      this.user.email = ''
    },
    cancel () {
      this.isProfileEditing = false
      this.isProfileDirty = false
      if (!this.isReadOnly) {
       this.isReadOnly = true
       this.user.email = this.cache.user.email
      }
    },
    setDirty () {
      this.isProfileDirty = true
    }
  }
})

2 个答案:

答案 0 :(得分:1)

要监听对象中某个属性的更改,您应该添加深度监视程序。为此,将deep: true属性添加到您的观察者。

watch: {
  user: {
    handler: function (newUser, oldUser) {
      console.log('Old User Email: ', oldUser.email)
      console.log('New User Email: ', newUser.email)
    },
    deep: true
  }
}

这里是updated pen

但是,如果您尝试使用oldUser,则观察者无法帮助您,因为:

  

注意:当更改(而不是替换)对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组。 Vue不会保留突变前值的副本。

这就是更新newUseroldUseruser.email的值相同的原因。

参考-vm.watch API

答案 1 :(得分:0)

如果要监视嵌套数据的更改,则必须设置监视程序的deep选项。但是,您无法在处理程序中访问旧数据,因为Vue不会保留对象的突变前值的副本。就您而言,watch对象的代码如下所示:

watch: {
  user: {
    handler: function (newUser) {
      console.log('New User Email: ', newUser.email)
    },
    deep: true
  }
}

参考:Vue's official API