sourcecode

Vue.js2 - Object.assign({}, this.var)을 차단하는 감시 메서드

copyscript 2022. 8. 17. 23:53
반응형

Vue.js2 - Object.assign({}, this.var)을 차단하는 감시 메서드

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이 userProfile에 변경 사항이 적용될 때마다 true로 설정됩니다(입력 시 v-model을 통해).

<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>

누가 왜 이런 일이 일어나는지 설명하고 실행 가능한 해결책을 제안할 수 있습니까?

계산된 속성은 종속성 중 일부가 변경된 경우에만 재평가됩니다.(소스)

그래서 이 기능이return this.user와 함께가 아니라Object.assign반응 의존성이 아니기 때문입니다.

반응성 데이터를 원하는 경우 초기화해야 합니다.userFormDataVue 인스턴스가 생성될 때 빈 개체 데이터로 사용자를 할당합니다.

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

다른 것을 테스트하고, 표시되는 동작을 재현.

당신의 템플릿에서 당신의 입력은 다음과 같이 구속되어 있는 것 같습니다.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>

코드명: https://codepen.io/aurelien-bottazini/pen/BVNJaG?editors=1010

$emit을 사용하여 개체에 값을 할당할 수 있습니다.

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

언급URL : https://stackoverflow.com/questions/50631769/vue-js2-object-assign-this-var-preventing-watch-method

반응형