Home > database >  Vue watch on objects
Vue watch on objects

Time:01-12

I'm using Vue2 and I have a problem to compare objects. But when compare "newVal" and "oldVal" values are always the same.

Child componenet:

name: "List",
    components: {
        Pagination, UserDetails
    },
    props: {
        filters: Object
    },
    watch: {
        filters: {
            handler(val, oldVal) {
                console.log(JSON.stringify(val));
                console.log(JSON.stringify(oldVal));
            },
            deep: true,
        }
    },

Parent Componenet:

<template>
    <div>
        <b-form inline>
            <label  for="inline-form-input-name">Name</label>
            <b-form-input
                id="inline-form-input-name"
                
                v-model="filters.username"
                placeholder="Name"
            ></b-form-input>

            <label  for="inline-form-input-username">Email</label>
            <b-input-group >
                <b-form-input
                    id="inline-form-input-username"
                    v-model="filters.email"
                    placeholder="Email"></b-form-input>
            </b-input-group>
            <b-button variant="danger">Clear</b-button>
        </b-form>
        <List :filters="filters"/>
    </div>
</template>

<script>

import List from "./List";

export default {
    name: "AdminUserList",
    components: {
        List,
    },
    data() {
        return {
            filters: {
                username: '',
                email: ''
            },
        }
    },
}
</script>

<style lang="scss">

</style>

Result:

{"username":"d","email":""}

{"username":"d","email":""}

CodePudding user response:

from the official doc you will find:

Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.

vue js watcher DOC

one thing that you can do is to watch the object's property directly like:

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      filters: {
        name: '',
        email: '',
      },
    };
  },
  watch: {
    'filters.name' (newVal, oldVal) {
      console.log(`new name: ${newVal}`, `, old name: ${oldVal}`);
    },
    'filters.email' (newVal, oldVal) {
      console.log(`new email: ${newVal}`, `, old email: ${oldVal}`);
    },
  },
});
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>

<div id="app">
  <v-app>
    <v-container>
      <v-row >
        <v-text-field v-model="filters.name" outlined label="name"></v-text-field>
      </v-row>
      <v-row >
        <v-text-field v-model="filters.email" outlined label="email"></v-text-field>
      </v-row>
    </v-container>
  </v-app>
</div>

CodePudding user response:

Try to adjust watcher accordingly

watch: {
    filters: {
        handler: function(val, oldVal) {
            console.log(JSON.stringify(val));
            console.log(JSON.stringify(oldVal));
        },
        deep: true,
    }
},

I have just followed documentation from the official website

  •  Tags:  
  • Related