Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

919
Views
¿Cuál es la diferencia entre ref, toRef y toRefs?

Acabo de empezar a trabajar con Vue 3 y la API de composición.

Me preguntaba cuáles son las diferencias entre ref , toRef y toRefs .

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

ref vue 3

Un ref es un mecanismo de reactividad en Vue 3. La idea es envolver un no-objeto en un objeto reactive :

Toma un valor interno y devuelve un objeto ref reactivo y mutable. El objeto ref tiene una sola propiedad .value que apunta al valor interno.

¿Hmm por que?

En JavaScript (y muchos lenguajes OOP), hay 2 tipos de variables: valor y referencia .

Variables de valor: si una variable x contiene un valor como 10 , es una variable de valor . Si tuviera que copiar x a y , simplemente copia el valor. Cualquier cambio futuro en x no cambiará y .

Variables de referencia : pero si x contiene un objeto, entonces es una variable de referencia . Con estos, las propiedades de y cambian cuando cambian las propiedades de x , porque ambas se refieren al mismo objeto. (Prueba esto con Vanilla JavaScript si te sorprende).

Esto hace que las variables de referencia sean más dinámicas en cierto sentido y más útiles para la reactividad, ya que cualquier cambio puede reflejarse fácilmente en cualquier parte de la aplicación. Vue quiere aprovechar esta capacidad incluso para variables de valor simple, por lo que ref las envuelve en un objeto, lo que crea una variable de referencia.

reactive

Para las variables de objeto, no se necesita un ajuste de referencia porque ya es un tipo de referencia. Solo necesita la funcionalidad reactiva de Vue (que también tiene un ref):

 const state = reactive({ foo: 1, bar: 2 })

Pero las propiedades de este objeto pueden contener valores en lugar de referencias. Si tuviera que copiar una propiedad de valor directamente a otra ubicación, la copia perdería la conexión con el objeto y su reactividad. Aquí es donde toRef es útil.

toRef

toRef convierte una sola propiedad de objeto reactive en una ref que mantiene su conexión con el objeto principal:

 const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') /* fooRef: Ref<number>, */

toRefs

toRefs convierte todas las propiedades en un objeto simple con propiedades que son referencias:

 const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) /* { foo: Ref<number>, bar: Ref<number> } */
over 4 years ago · Santiago Trujillo Report

0

reactivo

reactive crea un objeto proxy profundamente reactivo basado en un objeto dado. El objeto proxy se verá exactamente igual que el objeto simple dado, pero cualquier mutación, sin importar qué tan profunda sea, será reactiva; esto incluye todo tipo de mutaciones, incluidas las adiciones y eliminaciones de propiedades. Lo importante es que reactive solo puede funcionar con objetos, no con primitivos.

Por ejemplo, const state = reactive({foo: {bar: 1}}) significa:

  • state.foo es reactivo (se puede usar en plantilla, computar y observar)
  • state.foo.bar es reactivo
  • state.baz , state.foo.baz , state.foo.bar.baz también son reactivos aunque baz aún no existe en ninguna parte. Esto puede parecer sorprendente (especialmente cuando comienzas a investigar cómo funciona la reactividad en vue). Cuando state.baz es reactivo , me refiero a que dentro de su plantilla/propiedades computadas/relojes, puede escribir state.baz literalmente y esperar que su lógica se ejecute nuevamente cuando state.baz esté disponible . De hecho, incluso si escribes algo como {{ state.baz ? state.baz.qux : "default value" }} en su plantilla, también funcionará. La cadena final que se muestra reflejará reactivamente state.baz.qux.

Esto puede suceder porque reactive no solo crea un solo objeto proxy de nivel superior, sino que también convierte recursivamente todos los objetos anidados en proxies reactivos, y este proceso continúa en tiempo de ejecución incluso para los subobjetos creados sobre la marcha. Las dependencias de las propiedades de los objetos reactivos se descubren y rastrean continuamente en tiempo de ejecución cada vez que se realiza un intento de acceso a la propiedad contra un objeto reactivo . Con esto en mente, puedes resolver esta expresión {{ state.baz ? state.baz.qux : "default value" }} paso a paso:

  1. la primera vez que se evalúa, la expresión leerá baz off state (en otras palabras, se intenta un acceso a la propiedad on state para la propiedad baz ). Al ser un objeto proxy, state recordará que su expresión depende de su propiedad baz , aunque baz aún no existe. La reactividad de baz la proporciona el objeto de state que posee la propiedad .
  2. dado que state.baz devuelve undefined , la expresión se evalúa como "valor predeterminado" sin molestarse en mirar state.baz.qux . No hay ninguna dependencia registrada en state.baz.qux en esta ronda, pero está bien. Porque no puedes mutar qux sin mutar baz primero .
  3. en algún lugar de su código, asigna un valor a state.baz : state.baz = { qux: "hello" } . Esta mutación califica como una mutación de la propiedad baz de state , por lo tanto, su expresión está programada para una reevaluación. Mientras tanto, lo que se asigna a state.baz es un subproxy creado sobre la marcha para { qux: "hello" }
  4. su expresión se evalúa nuevamente, esta vez state.baz no está undefined , por lo que la expresión avanza a state.baz.qux . Se devuelve "hola" y se registra una dependencia en la propiedad qux del objeto proxy state.baz . Esto es lo que quiero decir con que las dependencias se descubren y registran en tiempo de ejecución a medida que ocurren .
  5. algún tiempo después cambias state.baz.qux = "hi" . Esta es una mutación de la propiedad qux y, por lo tanto, su expresión se evaluará nuevamente.

Con lo anterior en mente, también debería poder entender esto: puede almacenar state.foo en una variable separada: const foo = state.foo . La reactividad funciona bien con tu variable foo . foo apunta a lo mismo que state.foo apunta: un objeto proxy reactivo. El poder de la reactividad proviene del objeto proxy. Por cierto, const baz = state.baz no funcionaría igual, más sobre esto más adelante.

Sin embargo, siempre hay casos extremos a tener en cuenta:

  1. la creación recursiva de proxies anidados solo puede ocurrir si hay un objeto anidado. Si una propiedad dada no existe, o existe pero no es un objeto, no se puede crear ningún proxy en esa propiedad. Por ejemplo, esta es la razón por la que la reactividad no funciona con la variable baz creada por const baz = state.baz , ni con la variable bar de const bar = state.foo.bar . Para que quede claro, lo que significa es que puede usar state.baz y state.foo.bar en su plantilla/computado/reloj, pero no baz o bar creado anteriormente.
  2. si extrae un proxy anidado en una variable, se separa de su padre original. Esto se puede aclarar con un ejemplo. La segunda asignación a continuación ( state.foo = {bar: 3} ) no destruye la reactividad de foo , pero state.foo será un nuevo objeto proxy mientras que la variable foo todavía apunta al objeto proxy original.
 const state = reactive({foo: {bar: 1}}); const foo = state.foo; state.foo.bar = 2; foo.bar === 2; // true, because foo and state.foo are the same state.foo = {bar: 3}; foo.bar === 3; // false, foo.bar will still be 2

ref y toRef resuelven algunos de estos casos extremos.

árbitro

ref es más o menos el reactive que funciona también con primitivas. Todavía no podemos convertir las primitivas JS en objetos Proxy, por lo que ref siempre envuelve el argumento proporcionado X en un objeto de forma {value: X} . No importa si X es primitivo o no, el "boxeo" siempre ocurre. Si se le da un objeto a ref , ref llama internamente a reactive después del boxeo, por lo que el resultado también es profundamente reactivo. La principal diferencia en la práctica es que debe tener en cuenta llamar a .value en su código js cuando trabaje con ref. En su plantilla, no tiene que llamar a .value porque Vue desenvuelve automáticamente la referencia en la plantilla.

 const count = ref(1); const objCount = ref({count: 1}); count.value === 1; // true objCount.value.count === 1; // true

aRef

toRef está destinado a convertir una propiedad de un objeto reactivo en una ref . Quizás se pregunte por qué esto es necesario, ya que el objeto reactivo ya es profundamente reactivo. toRef está aquí para manejar los dos casos extremos mencionados para reactive . En resumen, toRef puede convertir cualquier propiedad de un objeto reactivo en una referencia vinculada a su padre original. La propiedad puede ser una que no exista inicialmente, o cuyo valor sea primitivo.

En el mismo ejemplo donde el estado se define como const state = reactive({foo: {bar: 1}}) :

  • const foo = toRef(state, 'foo') será muy similar a const foo = state.foo pero con dos diferencias:
    1. foo es una ref , por lo que debe hacer foo.value en js;
    2. foo está vinculado a su padre, por lo que reasignar state.foo = {bar: 2} se reflejará en foo.value
  • const baz = toRef(state, 'baz') ahora funciona.

aRefs

toRefs es un método de utilidad utilizado para destruir un objeto reactivo y convertir todas sus propiedades en ref:

 const state = reactive({...}); return {...state}; // will not work, destruction removes reactivity return toRefs(state); // works
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!