VueJS – $Watch e uma pequena comparação para os que vieram do Angular1.x

image_pdfimage_print

No Angular1.x, é comum se utilizar o $watch e notar que mesmo que o valor inicial observado não seja ‘modificado’ explicitamente, logo em seguida a criação do $watch, a primeira execução da função callback sempre ocorre (ou aparenta sempre acontecer).

Isto parece ocorrer por uma escolha na implementação (1.2 até 1.4.x. No 1.5 parece que já ocorreu pequenas alterações neste comportamento), que faz com que o status inicial de variáveis do $scope seja inicialmente undefined na fase de compilação para em seguida passar a ter um valor no template. E isto afeta a directive também. E $watch por exemplo dentro de directives tenderão a ser afetados por esta ‘mudança’ de valores. A única possibilidade de não haver esta execução inicial é o valor que está sendo observado também retornasse um undefined, o que tende a ser bem improvável.

Lembrando que um undefined === undefined. E por que lembrar isto é importante?

Basta dar uma acessada neste artigo e também lembrar de coisas como:

if(NaN === NaN){
    console.log("Nunca vou aparecer ou ser executado");
} else {
    console.log("Não estranha não. É isto mesmo. Não sou igual");
}

if(NaN == NaN){
    console.log("Nunca vou aparecer ou ser executado");
} else {
    console.log("É isto mesmo, agora acredita? Não sou igual");
}

Com isto, há uma execução imediata do callback do $watch no Angular1.x, tirando a exceção acima apresentada. (pelo menos da versão 1.2 a 1.4).

No entanto no Vue.js, este comportamento é mais estruturado e organizado. A execução imeditada do $watch só acontecerá se for explicitamente informado. Os parâmetros do $watch do Angular1.x e do Vue.js são um pouco diferente.

O do Angular1.x pode ser visto nesta artigo em maior detalhe.

Mas basicamente é $watch( o_que_observar_var_ou_funcao, funcao_executar_quando_diferente, observar_elementos_internos_do_objeto_sim_ou_nao);

Grosseiramente falando, a diferença para o vue está no terceiro argumento, que não será um boolean, cujo valor inicial é false. Será um objeto que pode ter dois atributos:

deep: Irá analisar os valores internos de um objeto caso seja true.
immediate: Irá executar o $watch com o primeiro valor avaliado de imediato. Caso contrário, somente quando houver alteração.

vm.$watch(function(){ return this.v1 + this.v2; },function(novo_valor,antigo_valor){
    //Serei executado na mudança de valor de this.v1+this.v2
    //Por conta da opção 'immediate' abaixo, serei executado assim que for inicializado com o valor inicial que estiver em this.v1+this.v2
}.{
    immediate: true
    ,deep: false
});

Fica ai a dica para aqueles que estão migrando ou que trabalham com as duas bibliotecas!

Gostou? Tire um minutinho e dê sua contribuição para Drall Dev Community no Patreon!