21 - Componentes: definición de métodos y modelo de datos

Igual que las instancias de la clase Vue, las componentes pueden tener una propiedad methods y data.

En la propiedad methods definimos todas las funciones y en la propiedad data a diferencia de la instancia Vue debemos plantear una función que retorne un objeto literal con todos los atributos de la componente (es importante recordar que la mecánica es distinta a los objetos Vue)

Problema

Plantear una componente llamada 'selector-numerico' con tres propiedades 'valor','minimo' y 'maximo'. En su interior definir dos botones que permitan incrementar o decrementar en uno el valor seleccionado actualmente:

<!doctype html>
<html>
<head>
  <title>Prueba Vue</title> 
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
  <div id="aplicacion">
    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>
  </div>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>

  Vue.component('selector-numerico', {
    props:['valor', 'minimo', 'maximo'],
    template: `<div><span style="width:1rem;display:inline-block;background:#ff0">{{cant}}</span>
                 <button v-on:click="incrementar()">+</button>
                 <button v-on:click="decrementar()">-</button>
               </div>`,
    data: function() {
      return {
        cant: this.valor
      }
    },
    methods: {
      incrementar: function() {
        if (this.cant<this.maximo)
          this.cant++;
      },
      decrementar: function() {
        if (this.cant>this.minimo)
          this.cant--;
      }      
    }
  })

  new Vue({
    el:'#aplicacion'
  })

</script>
</body>
</html>

En el bloque de HTML definimos una etiqueta de tipo 'selector-numerioco' y le pasamos los valores de las tres propiedades:

    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>

A las propiedades minimo, maximo y valor le antecedemos la directiva v-bind con el fin que Vue convierta los datos a tipo Number, sino en las propiedades de la componente se tratan como String.

Cuando creamos la componente 'selector-numerico' definimos sus tres propiedades:

  Vue.component('selector-numerico', {
    props:['valor', 'minimo', 'maximo'],

En la propiedad template definimos la interfaz visual de la componente y capturamos el evento click de cada botón para llamar a los métodos respectivos definidos en la componente:

    template: `<div><span style="width:1rem;display:inline-block;background:#ff0">{{cant}}</span>
                 <button v-on:click="incrementar()">+</button>
                 <button v-on:click="decrementar()">-</button>
               </div>`,

La propiedad data es una función que retorna un objeto literal con el modelo de datos de nuestra componente (en el modelo de datos definimos el atributo 'cant' que se inicializa con el valor de la propiedad 'valor' de la componente. Algo muy importante que haremos notar es que la componente nunca debe modificar el valor de las propiedades sino debe modificar propiedades definidas en 'data'):

    data: function() {
      return {
        cant: this.valor
      }
    },

La componente 'selector-numerico' define dos métodos, en el primero incrementa el atributo 'cant' y en el otro lo disminuye siempre y cuando no se salgan del rango especificado en las propiedades 'minimo' y 'maximo':

    methods: {
      incrementar: function() {
        if (this.cant<this.maximo)
          this.cant++;
      },
      decrementar: function() {
        if (this.cant>this.minimo)
          this.cant--;
      }      
    }
  })

Tengamos en cuenta que podemos definir luego más de una componente de tipo 'selector-numerico':

    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>
    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>
    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>
    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>
    <selector-numerico v-bind:valor="1" v-bind:minimo="0" v-bind:maximo="20"></selector-numerico>

Luego en la página tenemos como resultado:

Ejecutar Ejemplo

Resolver problema propuesto

Retornar