Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuejs get old value when on change event

Please refer to my snippet below. How can I get the old value of the changed model, in this case is the age in vuejs?

var app = new Vue({    el:"#table1",    data:{     items:[{name:'long name One',age:21},{name:'long name Two',age:22}]    },    methods:{      changeAge:function(item,event){        alert(item.age);      }    }  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <script src="https://unpkg.com/vue/dist/vue.js"></script>    <table class="table table-cart" id="table1">     <thead>       <tr>         <th>Name</th>         <th>Age</th>       </tr>    </thead>     <tbody>       <tr v-for="(item,index) in items">         <td>{{item.name}} :</td>                <td>           <input type="text" name="qty"                  v-model="item.age"                     @change="changeAge(item,$event)">         </td>       </tr>     </tbody>   </table>

I am trying to use watch, but I am not able to find any help in watching the age an array of items.

like image 698
madi Avatar asked Feb 13 '17 06:02

madi


People also ask

How do I watch data changes on Vue instance?

A Watcher in Vue. js is a special feature that allows one to watch a component and perform specified actions when the value of the component changes. It is a more generic way to observe and react to data changes in the Vue instance. Watchers are the most useful when used to perform asynchronous operations.

How do you find the value of old inputs?

To get old value with onchange() event in text box with JavaScript, we can get the old value when the click event is emitted. const input = document. querySelector("input"); input.

What is V model lazy in Vue?

.lazy. By default, v-model syncs the input with the data after each input event (with the exception of IME composition as stated above). You can add the lazy modifier to instead sync after change events: template <!--


1 Answers

This solution assumes that you need the old value only when handling the change coming from user input - which is probably the case, and not a generic model change. Below I added a sketch of solution watching all changes in if it's necessary, though perhaps it's better to control the other changes at the places they occur, and not in this component.

Drop v-model and replace it with manual handling.

It is important to note that "although a bit magical, v-model is essentially syntax sugar for updating data on user input events (...)". So without much harm you can remove it and handle the events directly, as you already almost do.

First, replace v-model with :value. The input will still follow the item.age updates, but will not update the age automatically.

<input type="text" name="qty"        :value="item.age"        @change="changeAge(item,$event)"> 

Then, in order to actually update the value, add item.age = event.target.value to changeAge, like this:

changeAge: function(item, event){   alert(item.age);  // Old value   alert(event.target.value);  // New value   item.age = event.target.value;  // Actual assignment } 

Note: you may want to use @input instead, that's what v-model actually uses.

And that's it, it should do the trick. If you need to prevent the change, you can just omit the assignment, however, you need to reset the input value. item.age = item.age of Vue.set(item, 'age', item.age) may do the trick, but I'm not quite sure it will.

Note: event.target.value is a string, if you need a number, use parseInt().

Create a separate component instance for every item and create a watch there

In case you need to watch all the changes. However, if you need that, perhaps you should do that in some other place, not this component.

I don't have all the details ready, so I'll just the general draft: in your v-for, instead of plain <input>, you place another component, say <my-item>. You put v-model=item on it. Inside the component, you create the <input> and forward the value prop to it, as well as forward it's input/change events outside. In your component single item is a single prop, so you can attach a watcher directly to it. Relevant docs: Component Basics, Customizing Component v-model, Props.

like image 170
Frax Avatar answered Sep 19 '22 04:09

Frax