I have a JSON object that looks like this,
[
{
"column": {
"name": "31_12_2021",
"display_name": "31/12/2021",
"default_value": "",
"pk": true,
"hidden": false,
"data_type": "1"
},
"header_row": {
"style": {}
},
"data_rows": [
{
"style": {}
},
{
"style": {}
}
]
},
{
"column": {
"name": "quick",
"display_name": "quick",
"default_value": "",
"pk": false,
"hidden": false,
"data_type": "1"
},
"header_row": {
"style": {}
},
"data_rows": [
{
"style": {}
},
{
"style": {}
}
]
},
{
"column": {
"name": "333",
"display_name": "333",
"default_value": "",
"pk": false,
"hidden": false,
"data_type": "1"
},
"header_row": {
"style": {}
},
"data_rows": [
{
"style": {}
},
{
"style": {}
}
]
}
]
I am looping over this in my vue template to create a select menu,
<div v-for="(c, i) in columns" :key="i">
<select v-model="c.column.data_type">
<option value="1">Data Type 1</option>
<option value="2">Data Type 2</option>
<option value="3">Data Type 3</option>
<option value="4">Data Type 4</option>
</select>
</div>
By binding the select to the data_type every time I make a select change it updates the data for that object in my data/json. What I want to know is it possible to get the old value before it was changed?
I have tried to do something like,
watch: {
columns: {
deep: true,
handler(newValue, oldValue) {
//do some comparions here
}
}
}
But it appears that newValue and oldValue are the same?
CodePudding user response:
You would be better off using an @input event on your select, if you only want to see if one property has changed. I've included a working snippet below showing how you can get the old and new value.
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: "#app",
data: () => {
return {
columns: [{
"column": {
"name": "31_12_2021",
"display_name": "31/12/2021",
"default_value": "",
"pk": true,
"hidden": false,
"data_type": "1"
},
"header_row": {
"style": {}
},
"data_rows": [{
"style": {}
}, {
"style": {}
}]
}, {
"column": {
"name": "quick",
"display_name": "quick",
"default_value": "",
"pk": false,
"hidden": false,
"data_type": "1"
},
"header_row": {
"style": {}
},
"data_rows": [{
"style": {}
}, {
"style": {}
}]
}, {
"column": {
"name": "333",
"display_name": "333",
"default_value": "",
"pk": false,
"hidden": false,
"data_type": "1"
},
"header_row": {
"style": {}
},
"data_rows": [{
"style": {
}
}, {
"style": {
}
}]
}]
}
},
methods: {
onDataTypeChange: function(oldValue, newValue) {
alert("Changed from " oldValue " to " newValue);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(c, i) in columns" :key="i">
<select v-model="c.column.data_type" @input="onDataTypeChange(c.column.data_type, $event.target.value)">
<option value="1">Data Type 1</option>
<option value="2">Data Type 2</option>
<option value="3">Data Type 3</option>
<option value="4">Data Type 4</option>
</select>
</div>
</div>
CodePudding user response:
As mentioned in the docs
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.
One possible way of circumventing this challenge is to use @Shoejep's solution
