Skip to content

Fundamentos de Reactividad

Preferencias de API

Esta página y muchos otros capítulos posteriores en la guía tienen contenido diferente para la Options API y la Composition API. Tu preferencia actual es Options APIComposition API. Puedes alternar entre los estilos de API usando el interruptor de "Preferencia de API" en la parte superior de la barra lateral izquierda.

Declarando el Estado Reactivo

Con la Options API, usamos la opción data para declarar el estado reactivo de un componente. El valor de la opción debe ser una función que devuelva un objeto. Vue llamará a la función al crear una nueva instancia del componente y empaquetará el objeto devuelto en su sistema de reactividad. Cualquier propiedad de nivel superior de este objeto se representa en la instancia del componente (this en los métodos y hooks del ciclo de vida):

js
export default {
  data() {
    return {
      count: 1
    }
  },

  // `mounted` es un hook del ciclo de vida que explicaremos luego
  mounted() {
    // `this` se refiere a la instancia del componente.
    console.log(this.count) // => 1

    // los datos también pueden ser mutados
    this.count = 2
  }
}

Pruébalo en la Zona de Práctica

Estas propiedades de la instancia solo se agregan cuando la instancia se crea por primera vez, por lo que debes asegurarte que estén todas presentes en el objeto devuelto por la función data. Cuando sea necesario, usa null, undefined o algún otro valor de marcador de posición para las propiedades donde el valor deseado aún no está disponible.

Es posible agregar una nueva propiedad directamente al this sin incluirla en data. Sin embargo, las propiedades agregadas de esta manera no podrán desencadenar actualizaciones reactivas.

Vue usa el prefijo $ cuando expone sus propias API integradas a través de la instancia del componente. También reserva el prefijo _ para propiedades internas. Debes evitar el uso de nombres para las propiedades de nivel superior de data que comiencen con cualquiera de estos caracteres.

Proxy Reactivo vs. Original

En Vue 3, los datos se vuelven reactivos al aprovechar los Proxies de JavaScript. Los usuarios que vienen de Vue 2 deben tener en cuenta el siguiente caso extremo:

js
export default {
  data() {
    return {
      someObject: {}
    }
  },
  mounted() {
    const newObject = {}
    this.someObject = newObject

    console.log(newObject === this.someObject) // false
  }
}

Cuando accedes a this.someObject después de asignarlo, el valor es un proxy reactivo del newObject original. A diferencia de Vue 2, el newObject original se deja intacto y no se volverá reactivo: asegúrate de acceder siempre al estado reactivo como una propiedad de this.

Declarando Estado Reactivo

### ref() **

En la Composition API, la manera recomendada de declarar estado reactivo es usando la función ref():

js
import { ref } from 'vue'

const count = ref(0)

ref() toma el argumento y lo devuelve empaquetado en un objeto ref con la propiedad .value:

js
const count = ref(0)

console.log(count) // { value : 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

Consulta también: Escritura de Refs

Para usar refs en la plantilla de un componente, decláralos y devuélvelos desde la función setup() del componente:

js
import { ref } from 'vue'

export default {
  // `setup` es un hook especial dedicado para la Composition API.
  setup() {
    const count = ref(0})

    // expone la ref a la plantilla
    return {
      count
    }
  }
}
template
<div>{{ count }}</div>

Nota que no necesitamos agregar .value al usar la ref en la plantilla. Por conveniencia, las refs son desenvueltos automáticamente al ser usadas dentro de plantillas (con algunas advertencias).

También puedes mutar una ref directamente en manejadores de eventos:

template
<button @click="count++">
  {{ count }}
</button>

Para lógica más compleja, podemos declarar funciones que mutan refs en el mismo ámbito y exponerlas como métodos junto con el estado:

js
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)

    function increment() {
      // .value es necesario en JavaScript
      count.count++
    }

    // no te olvides de exponer la función también.
    return {
      count,
      increment
    }
  }
}

Los métodos expuestos pueden después ser usados como manejadores de eventos:

template
<button @click="increment">
  {{ count }}
</button>

Acá hay un ejemplo en CodePen, sin usar herramientas de compilación.

<script setup>