ebyratu
ebyratu

Reputation: 293

Vue v-model input change mobile chrome not work

If i open https://v2.vuejs.org/v2/guide/forms.html#Text and edit text - no effect on typing text in mobile chrome. @keyup @input @keypress - v-model does not change when I'm typing

<input v-model="message" @keyup="log" placeholder="Edit">
<p>Edited: {{ message }}</p>

How can i fix it? I need get input value on typing (@keyup @input)

Upvotes: 14

Views: 13064

Answers (4)

Josuah Aron
Josuah Aron

Reputation: 161

EDIT: A simpler solution for me was to just use @input.native. Also, the this event has (now?) a isComposing attribute which we can use to either take $event.data into account, or $event.target.value

In my case, the only scheme that worked was handling @keydown to save the value before the user action, and handling @keyup to process the event if the value had changed. NOTE: the disadvantage of this is that any non-keyboard input (like copy/paste with a mouse) will not work.

<md-input
    v-else
    :value="myValue"
    ref="input"
    @keydown="keyDownValue = $event.target.value"
    @keyup="handleKeyUp($event)"
    @blur="handleBlur()"
/>

With handleKeyUp in my case being:

handleKeyUp(evt){
  if(evt.target.value !== this.keyDownValue){
    this.$emit('edited', evt);
  }
}

My use case was the following:

I requested a search endpoint in the backend to get suggestions as the user typed. Solutions like handling @compositionupdate lead to sending several several requests to the backend (I also needed @input for non-mobile devices). I reduced the number of requests sent by correctly handling @compositionStarted, but there was still cases where 2 requests were sent for just 1 character typed (when composition was left then, e.g. with space character, then re-entered, e.g. with backspace character).

Upvotes: 0

rompish
rompish

Reputation: 123

I tried all solutions I could find on the internet, nothing worked for me. in the end i came up with this, finally works on android!

Trick is to use compositionupdate event:

 <input type="text" ... v-model="myinputbox" @compositionupdate="compositionUpdate($event)">
    
    ......
    ......

methods: {
    compositionUpdate: function(event)
    {
        this.myinputbox = event.data;
    },
}

Upvotes: 5

bbsimonbb
bbsimonbb

Reputation: 29002

Update: After a lot of discussion, I've come to understand that this is a feature, not a bug. v-model is more complicated than you might at first think, and a mobile 'keyboard' is more complicated than a keyboard. This behaviour can surprise, but it's not wrong. Code your @input separately if you want something else.


Houston we might have a problem. Vue does not seem to be doing what it says on the tin. V-model is supposed to update on input, but if we decompose the v-model and code the @input explicitly, it works fine on mobile. (both inputs behave normally in chrome desktop)

For display on mobiles, the issue can be seen at... https://jsbin.com/juzakis/1

See this github issue.

function doIt(){
    var vm = new Vue({
        el : '#vueRoot',
        data : {message : '',message1 : ''}
    })
}
doIt();
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id='vueRoot'>
<h1>v-model</h1>
  <div>
    <input type='text'
      v-model='message'
        >
    {{message}}
  </div>
  <h1>Decomposed</h1>
  <div>
    <input type='text'
        :value='message1'
        @input='evt=>message1=evt.target.value'
        >
    {{message1}}
  </div>
</div>

Upvotes: 27

Diego Meza
Diego Meza

Reputation: 304

Ok, I dont know if there is another solution for this issue, but it can be solved with a simple directive:

Vue.directive('$model', {
    bind: function (el, binding, vnode) {
        el.oninput = () => (vnode.context[binding.expression] = el.value)
    }
})

using it just like

<input v-$model="{toBind}">

There is an issue on the oficial repo, and they say this is the normal behavior (because the composition mode), but I still need the functionality

Upvotes: 1

Related Questions