Como disparar um evento quando o modelo v muda?

90

Estou tentando disparar a foo()função com o @clickmas, como você pode ver, preciso pressionar o botão de opção duas vezes para disparar o evento corretamente. Capture o valor apenas na segunda vez que você pressionar ...

Quero disparar o evento sem @clickapenas disparar o evento quando v-model(srStatus) for alterado.

aqui está meu violino:

http://fiddle.jshell.net/wanxe/vsa46bw8/

Jnieto
fonte
1
o link fiddle não está mais funcionando.
FrenkyB
Se a intenção da chamada foo()for fazer alterações não relacionadas ao modelo, use umwatcher
Saksham
Este é um ótimo exemplo de por que o código é necessário na pergunta . Se possível, recupere-o e mostre-o aqui.
isherwood
Eu gostaria de poder recuperar o código para a pergunta, mas isso já foi há 5 anos ... felizmente, temos boas respostas
jnieto

Respostas:

77

Isso acontece porque seu clickmanipulador dispara antes que o valor do botão de opção seja alterado. Em changevez disso, você precisa ouvir o evento:

<input 
  type="radio" 
  name="optionsRadios" 
  id="optionsRadios2" 
  value=""
  v-model="srStatus" 
  v-on:change="foo"> //here

Além disso, certifique-se de que realmente deseja ligar foo()pronto ... parece que talvez você não queira realmente fazer isso.

ready:function(){
    foo();
},
Pherris
fonte
Como você lidaria com os Sliders?
Royi de
onde estão os eventos disponíveis listados na documentação. Eu não consigo encontrar?
toraman
Estes são apenas eventos JavaScript padrão que você pode encontrar aqui: developer.mozilla.org/en-US/docs/Web/Events#Standard_events
pherris
Obrigado! Mas pronto: a função não funcionou para mim. Em vez disso, métodos: {foo () {// faça algo}}
Vince Banzon
Observe também que se você deseja registrar eventos "v-on: change" em um componente vue customizado (componente de arquivo único), "v-on: input" deve ser usado.
Andrés Biarge
94

Você pode realmente simplificar isso removendo as v-ondiretivas:

<input type="radio" name="optionsRadios" id="optionsRadios1" value="1" v-model="srStatus">

E use o watchmétodo para ouvir a mudança:

new Vue ({
    el: "#app",
    data: {
        cases: [
            { name: 'case A', status: '1' },
            { name: 'case B', status: '0' },
            { name: 'case C', status: '1' }
        ],
        activeCases: [],
        srStatus: ''
    },
    watch: {
        srStatus: function(val, oldVal) {
            for (var i = 0; i < this.cases.length; i++) {
                if (this.cases[i].status == val) {
                    this.activeCases.push(this.cases[i]);
                    alert("Fired! " + val);
                }
            }
        }
    }
});
Stephen Hallgren
fonte
2
Você pode assistir automaticamente qualquer mudança de modelo? Por exemplo, para um formulário com várias entradas que precisam ser monitoradas?
Eric Burel
@EricBurel Eu sei que isso é antigo, mas a resposta é não. Você não pode observar todo o objeto de dados ao qual todos os campos estão vinculados, você precisaria observar cada uma das propriedades desse objeto individualmente, tornando essa abordagem problemática para grandes registros em formulários com muitos campos.
JohnC
1
@EricBurel Na verdade, você pode observar objetos aninhados com a propriedade 'deep' definida como 'true' -> vuejs.org/v2/api/#watch
SanBen
28

Vue2: se você só deseja detectar mudanças no desfoque de entrada (por exemplo, depois de pressionar enter ou clicar em outro lugar), faça (mais informações aqui )

<input @change="foo" v-model... >

Se você quiser detectar alterações de um único caractere (durante a digitação do usuário), use

<input @keydown="foo" v-model... >

Você também pode usar @keyupe @inputeventos. Se você deseja passar parâmetros adicionais, use no modelo, por exemplo @keyDown="foo($event, param1, param2)". Comparação abaixo (versão editável aqui )

Kamil Kiełczewski
fonte
keyDown não funciona do que 'backspace' pressionado. Portanto, é melhor usar @input
Peretz30
Neste violino, vemos que backspace funciona com @keyDown jsfiddle.net/rLzm0f1q (no entanto, não digo que @inputseja bom ou ruim)
Kamil Kiełczewski
22

Você deve usar @input:

<input @input="handleInput" />

@input dispara quando o usuário altera o valor de entrada.

@change dispara quando o usuário altera o valor e desfoca a entrada (por exemplo, clica em algum lugar externo)

Você pode ver a diferença aqui: https://jsfiddle.net/posva/oqe9e8pb/

Peretz30
fonte
O que você pode usar em vez do sinal @? Existe alguma regra escrita em algum lugar sobre isso? Estou perguntando isso porque no meu back-end, o sinal @ está reservado para outra coisa.
FrenkyB