VueJS - Interface Reativa

O VueJS oferece opções para adicionar reatividade às propriedades, que são adicionadas dinamicamente. Considere que já criamos a instância vue e precisamos adicionar a propriedade watch. Isso pode ser feito da seguinte forma -

Exemplo

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "js/vue.js"></script>
   </head>
   <body>
      <div id = "app">
         <p style = "font-size:25px;">Counter: {{ counter }}</p>
         <button @click = "counter++" style = "font-size:25px;">Click Me</button>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#app',
            data: {
               counter: 1
            }
         });
         vm.$watch('counter', function(nval, oval) {
            alert('Counter is incremented :' + oval + ' to ' + nval + '!');
         });
         setTimeout(
            function(){
               vm.counter = 20;
            },2000
         );
      </script>
   </body>
</html>

Há um contador de propriedades definido como 1 no objeto de dados. O contador é incrementado quando clicamos no botão.

A instância Vue já foi criada. Para adicionar relógio a ele, precisamos fazer o seguinte -

vm.$watch('counter', function(nval, oval) {
   alert('Counter is incremented :' + oval + ' to ' + nval + '!');
});

Precisamos usar $ watch para adicionar watch fora da instância vue. Há um alerta adicionado, que mostra a alteração do valor da propriedade do contador. Há também uma função de temporizador adicionada, ou seja, setTimeout, que define o valor do contador para 20.

setTimeout(
   function(){
      vm.counter = 20;
   },2000
);

Sempre que o contador for alterado, o alerta do método de observação será disparado conforme mostrado na imagem a seguir.

O VueJS não pode detectar adição e exclusão de propriedade. A melhor maneira é sempre declarar as propriedades, que precisam ser reativas antecipadamente na instância do Vue. No caso de precisarmos adicionar propriedades em tempo de execução, podemos fazer uso dos métodos Vue global, Vue.set e Vue.delete.

Vue.set

Este método ajuda a definir uma propriedade em um objeto. É usado para contornar a limitação de que o Vue não pode detectar adições de propriedade.

Sintaxe

Vue.set( target, key, value )

Onde,

alvo: pode ser um objeto ou uma matriz

chave: pode ser uma string ou número

valor: pode ser qualquer tipo

Vamos dar uma olhada em um exemplo.

Exemplo

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "js/vue.js"></script>
   </head>
   <body>
      <div id = "app">
         <p style = "font-size:25px;">Counter: {{ products.id }}</p>
         <button @click = "products.id++" style = "font-size:25px;">Click Me</button>
      </div>
      <script type = "text/javascript">
         var myproduct = {"id":1, name:"book", "price":"20.00"};
         var vm = new Vue({
            el: '#app',
            data: {
               counter: 1,
               products: myproduct
            }
         });
         vm.products.qty = "1";
         console.log(vm);
         vm.$watch('counter', function(nval, oval) {
            alert('Counter is incremented :' + oval + ' to ' + nval + '!');
         });
      </script>
   </body>
</html>

No exemplo acima, há uma variável myproduct criada no início usando o seguinte trecho de código.

var myproduct = {"id":1, name:"book", "price":"20.00"};

É fornecido ao objeto de dados na instância Vue da seguinte forma -

var vm = new Vue({
   el: '#app',
   data: {
      counter: 1,
      products: myproduct
   }
});

Considere, queremos adicionar mais uma propriedade ao array myproduct, após a instância Vue ser criada. Isso pode ser feito da seguinte forma -

vm.products.qty = "1";

Vamos ver a saída no console.

Conforme visto acima, nos produtos a quantidade é adicionada. Os métodos get / set, que basicamente adicionam reatividade, estão disponíveis para id, nome e preço, e não para qty.

Não podemos alcançar a reatividade apenas adicionando o objeto vue. O VueJS deseja principalmente que todas as suas propriedades sejam criadas no início. No entanto, caso precisemos adicioná-lo posteriormente, podemos usar Vue.set. Para isso, precisamos defini-lo usando vue global, ou seja, Vue.set.

Exemplo

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "js/vue.js"></script>
   </head>
   <body>
      <div id = "app">
         <p style = "font-size:25px;">Counter: {{ products.id }}</p>
         <button @click = "products.id++" style = "font-size:25px;">Click Me</button>
      </div>
      <script type = "text/javascript">
         var myproduct = {"id":1, name:"book", "price":"20.00"};
         var vm = new Vue({
            el: '#app',
            data: {
               counter: 1,
               products: myproduct
            }
         });
         Vue.set(myproduct, 'qty', 1);
         console.log(vm);
         vm.$watch('counter', function(nval, oval) {
            alert('Counter is incremented :' + oval + ' to ' + nval + '!');
         });
      </script>
   </body>
</html>

Usamos Vue.set para adicionar o qty ao array usando o seguinte trecho de código.

Vue.set(myproduct, 'qty', 1);

Consolamos o objeto vue e o seguinte é o resultado.

Agora, podemos ver o get / set para qty adicionado usando Vue.set.

Vue.delete

Esta função é usada para excluir a propriedade dinamicamente.

Exemplo

Vue.delete( target, key )

Onde,

alvo: pode ser um objeto ou uma matriz

chave: pode ser uma string ou um número

Para excluir qualquer propriedade, podemos usar Vue.delete como no código a seguir.

Exemplo

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "js/vue.js"></script>
   </head>
   <body>
      <div id = "app">
         <p style = "font-size:25px;">Counter: {{ products.id }}</p>
         <button @click = "products.id++" style = "font-size:25px;">Click Me</button>
      </div>
      <script type = "text/javascript">
         var myproduct = {"id":1, name:"book", "price":"20.00"};
         var vm = new Vue({
            el: '#app',
            data: {
               counter: 1,
               products: myproduct
            }
         });
         Vue.delete(myproduct, 'price');
         console.log(vm);
         vm.$watch('counter', function(nval, oval) {
            alert('Counter is incremented :' + oval + ' to ' + nval + '!');
         });
      </script>
   </body>
</html>

No exemplo acima, usamos Vue.delete para excluir o preço da matriz usando o seguinte trecho de código.

Vue.delete(myproduct, 'price');

A seguir está a saída, vemos no console.

Após a exclusão, podemos ver apenas o id e o nome, pois o preço é excluído. Também podemos notar que os métodos get / set são excluídos.