Reactividad en Vue

 

 

 

  • Accesibilidad para diseñadores, con Stéphanie Walter
  • Creación y mantenimiento de sistemas de diseño exitosos, con Brad Fost

  • Índice
    1. El método reactivo
    2. ref
    3. toRefs
    4. toRef
    5. Conclusión
      1. Recursos adicionales

    La reactividad es la capacidad de una variable (matriz, cadena, número, objeto, etc.) de actualizarse cuando su valor o cualquier otra variable a la que hace referencia cambia después de la declaración.

     

    En este artículo, veremos la reactividad en Vue, cómo funciona y cómo podemos crear variables reactivas utilizando métodos y funciones recién creados. Este artículo está dirigido a desarrolladores que comprenden bien cómo funciona Vue 2.x y desean familiarizarse con el nuevo Vue 3 .

    Vamos a crear una aplicación sencilla para comprender mejor este tema. El código de esta aplicación se puede encontrar en GitHub .

    De forma predeterminada, JavaScript no es reactivo . Esto significa que si creamos la variable boyy hacemos referencia a ella en la parte A de nuestra aplicación, luego procedemos a modificarla boyen la parte B, la parte A no se actualizará con el nuevo valor de boy.

    let framework = 'Vue';let sentence = `${framework} is awesome`;console.log(sentence) // logs "Vue is awesome"framework = 'React';console.log(sentence)//should log "React is awesome" if 'sentence' is reactive.

    El fragmento anterior es un ejemplo perfecto de la naturaleza no reactiva de JavaScript; de ahí que el cambio no se refleje en la sentencevariable.

    En Vue 2.x, props, computedy data()eran todos reactivos de forma predeterminada, con la excepción de las propiedades que no están presentes datacuando se crean dichos componentes. Esto significa que cuando un componente se inyecta en el DOM , solo las propiedades existentes en el objeto del componente dataharían que el componente se actualice si dichas propiedades cambian.

    Internamente, Vue 3 usa el Proxyobjeto (una característica de ECMAScript 6) para garantizar que estas propiedades sean reactivas, pero aún brinda la opción de usarlo Object.definePropertydesde Vue 2 para compatibilidad con Internet Explorer (ECMAScript 5). Este método define una nueva propiedad directamente en un objeto, o modifica una propiedad existente en un objeto y devuelve el objeto.

     

    A primera vista y como la mayoría de nosotros ya sabemos que la reactividad no es nueva en Vue, puede parecer innecesario hacer uso de estas propiedades, pero la API de Opciones tiene sus limitaciones cuando se trata de una aplicación grande con funciones reutilizables en varios partes de la aplicación. Con este fin, se introdujo la nueva API de composición para ayudar a abstraer la lógica y hacer que el código base sea más fácil de leer y mantener. Además, ahora podemos hacer que cualquier variable sea reactiva independientemente de su tipo de datos utilizando cualquiera de las nuevas propiedades y métodos.

    Cuando usamos la setupopción, que sirve como punto de entrada para la API de composición, el dataobjeto, computedlas propiedades y methodsson inaccesibles porque la instancia del componente aún no se ha creado cuando setupse ejecuta. Esto hace que sea imposible aprovechar la reactividad incorporada en cualquiera de estas características en setup. En este tutorial, aprenderemos todas las formas en que podemos hacer esto.

    El método reactivo

    Según la documentación, el reactivemétodo, que es equivalente a Vue.observable()Vue 2.6, puede ser útil cuando intentamos crear un objeto cuyas propiedades sean reactivas (como el dataobjeto en la API de opciones). Debajo del capó, el dataobjeto en la API de opciones usa este método para hacer que todas las propiedades que contiene sean reactivas.

    Pero podemos crear nuestro propio objeto reactivo así:

    import { reactive } from 'vue'// reactive statelet user = reactive({ "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "[email protected]", "address": { "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", "geo": { "lat": "-37.3159", "lng": "81.1496" } }, "phone": "1-770-736-8031 x56442", "website": "hildegard.org", "company": { "name": "Romaguera-Crona", "catchPhrase": "Multi-layered client-server neural-net", "bs": "harness real-time e-markets" }, "cars": { "number": 0 } })

    Aquí, importamos el reactivemétodo de Vue y luego declaramos nuestra uservariable pasando su valor a esta función como argumento. Al hacerlo, lo hemos hecho userreactivo y, por lo tanto, si lo usamos useren nuestra plantilla y si el objeto o una propiedad de este objeto debe cambiar, entonces este valor se actualizará automáticamente en esta plantilla.

     

    ref

    Así como tenemos un método para hacer que los objetos sean reactivos, también necesitamos uno para hacer que otros valores primitivos independientes (cadenas, valores booleanos, valores indefinidos, números, etc.) y matrices sean reactivos. Durante el desarrollo, trabajaríamos con estos otros tipos de datos y al mismo tiempo necesitaríamos que fueran reactivos. El primer enfoque que podríamos pensar sería usar reactivey pasar el valor de la variable que queremos hacer reactiva.

    import { reactive } from 'vue'const state = reactive({ users: [],});

    Porque reactivetiene una conversión reactiva profunda, userya que una propiedad también sería reactiva, logrando así nuestro objetivo; por lo tanto, usersiempre se actualizará en cualquier lugar donde se use en la plantilla de dicha aplicación. Pero con la refpropiedad, podemos hacer que cualquier variable con cualquier tipo de datos sea reactiva pasando el valor de esa variable a ref. Este método también funciona para objetos, pero anida el objeto un nivel más profundo que cuando reactivese utiliza el método.

    let property = { rooms: '4 rooms', garage: true, swimmingPool: false}let reactiveProperty = ref(property)console.log(reactiveProperty)// prints {// value: {rooms: "4 rooms", garage: true, swimmingPool: false}// }

    Debajo del capó, reftoma este argumento que se le pasa y lo convierte en un objeto con una clave de value. Esto significa que podemos acceder a nuestra variable llamando variable.valuey también podemos modificar su valor llamándola de la misma manera.

    import {ref} from 'vue'let age = ref(1)console.log(age.value)//prints 1age.value++console.log(age.value)//prints 2

    Con esto, podemos importar refa nuestro componente y crear una variable reactiva:

    template div form @click.prevent="" table tr thName/th thUsername/th themail/th thEdit Cars/th thCars/th /tr tr v-for="user in users" :key="user.id" td{{ user.name }}/td td{{ user.username }}/td td{{ user.email }}/td td input type="number" name="cars" v-model.number="user.cars.number" / /td td cars-number :cars="user.cars" / /td /tr /table pTotal number of cars: {{ getTotalCars }}/p /form /div/templatescript // @ is an alias to /src import carsNumber from "@/components/cars-number.vue"; import axios from "axios"; import { ref } from "vue"; export default { name: "Home", data() { return {}; }, setup() { let users = ref([]); const getUsers = async () = { let { data } = await axios({ url: "data.json", }); users.value = data; }; return { users, getUsers, }; }, components: { carsNumber, }, created() { this.getUsers(); }, computed: { getTotalCars() { let users = this.users; let totalCars = users.reduce(function(sum, elem) { return sum + elem.cars.number; }, 0); return totalCars; }, };/script

    Aquí, importamos refpara crear una usersvariable reactiva en nuestro componente. Luego importamos axiospara recuperar datos de un archivo JSON en la publiccarpeta e importamos nuestro carsNumbercomponente, que crearemos más adelante. Lo siguiente que hicimos fue crear una usersvariable reactiva usando el refmétodo, para que userspueda actualizarse cada vez que cambie la respuesta de nuestro archivo JSON.

     

    También creamos una getUserfunción que recupera la usersmatriz de nuestro archivo JSON usando axios y asignamos el valor de esta solicitud a la usersvariable. Finalmente, creamos una propiedad calculada que calcula la cantidad total de automóviles que tienen nuestros usuarios tal como la modificamos en la sección de plantilla.

    Es importante tener en cuenta que al acceder a reflas propiedades que se devuelven en la sección de plantilla o fuera de ella setup(), se desenvuelven automáticamente de forma superficial . Esto significa que refsese es un objeto aún requeriría un .valuepara poder acceder. Como userses una matriz, simplemente podríamos usarla usersy no users.valueen getTotalCars.

    En la sección de plantilla, mostramos una tabla que muestra la información de cada usuario, junto con un cars-number /componente. Este componente acepta un carsaccesorio que se muestra en la fila de cada usuario como la cantidad de autos que tiene. Este valor se actualiza cada vez que cambia el valor cars del objeto de usuario , que es exactamente cómo funcionaría el dataobjeto o propiedad si estuviéramos trabajando con la API de opciones.computed

    toRefs

    Cuando usamos la API de composición, la setupfunción acepta dos argumentos: propsy context. Esto propsse pasa del componente a setup()y permite acceder a los accesorios que tiene el componente desde dentro de esta nueva API. Este método es particularmente útil porque permite desestructurar objetos sin perder su reactividad.

    template p{{ cars.number }}/p/templatescript export default { props: { cars: { type: Object, required: true, }, gender: { type: String, required: true, }, }, setup(props) { console.log(props); // prints {gender: "female", cars: Proxy} }, };/scriptstyle/style

    Para utilizar un valor que es un objeto propsen la API de composición y al mismo tiempo garantizar que mantenga su reactividad, utilizamos toRefs. Este método toma un objeto reactivo y lo convierte en un objeto simple en el que cada propiedad del objeto reactivo original se convierte en un archivo ref. Lo que esto significa es que la carspropiedad...

    cars: { number: 0}

    … ahora se convertiría en esto:

    { value: cars: { number: 0 }

    Con esto, podemos hacer uso de carscualquier parte de la API de configuración manteniendo su reactividad.

     

     setup(props) { let { cars } = toRefs(props); console.log(cars.value); // prints {number: 0} },

    Podemos observar esta nueva variable utilizando las API de composición watchy reaccionar a este cambio como queramos.

    setup(props) { let { cars } = toRefs(props); watch( () = cars, (cars, prevCars) = { console.log("deep ", cars.value, prevCars.value); }, { deep: true } ); }

    toRef

    Otro caso de uso común al que nos podríamos enfrentar es pasar un valor que no es necesariamente un objeto sino uno de los tipos de datos con los que funciona ref(matriz, número, cadena, booleano, etc.). Con toRef, podemos crear una propiedad reactiva (es decir, ref) a partir de un objeto reactivo de origen. Hacer esto garantizaría que la propiedad permanezca reactiva y se actualizaría cada vez que cambie la fuente principal.

    const cars = reactive({ Toyota: 1, Honda: 0})const NumberOfHondas = toRef(state, 'Honda')NumberOfHondas.value++console.log(state.Honda) // 1state.Honda++console.log(NumberOfHondas.value) // 2

    Aquí, creamos un objeto reactivo usando el reactivemétodo, con las propiedades Toyotay Honda. También utilizamos toRefpara crear una variable reactiva a partir de Honda. En el ejemplo anterior, podemos ver que cuando actualizamos Hondausando el objeto reactivo carso NumberOfHondas, el valor se actualiza en ambos casos.

    Este método es similar y, sin embargo, muy diferente del toRefsmétodo que cubrimos anteriormente en el sentido de que mantiene su conexión con su fuente y puede usarse para cadenas, matrices y números. A diferencia de con toRefs, no necesitamos preocuparnos por la existencia de la propiedad en su fuente en el momento de la creación, porque si esta propiedad no existe en el momento en que se refcrea y en su lugar regresa null, aún se almacenará como un archivo válido. propiedad, con una forma de watcherponer en marcha, de modo que cuando este valor cambie, este refuso creado toReftambién se actualizará.

    También podemos usar este método para crear una propiedad reactiva a partir de props. Se vería así:

    template p{{ cars.number }}/p/templatescript import { watch, toRefs, toRef } from "vue"; export default { props: { cars: { type: Object, required: true, }, gender: { type: String, required: true, }, }, setup(props) { let { cars } = toRefs(props); let gender = toRef(props, "gender"); console.log(gender.value); watch( () = cars, (cars, prevCars) = { console.log("deep ", cars.value, prevCars.value); }, { deep: true } ); }, };/script

    Aquí, creamos un refque se basaría en la genderpropiedad obtenida de props. Esto resulta útil cuando queremos realizar operaciones adicionales en el accesorio de un componente en particular.

    Conclusión

    En este artículo, analizamos cómo funciona la reactividad en Vue utilizando algunos de los métodos y funciones recientemente introducidos en Vue 3. Comenzamos analizando qué es la reactividad y cómo Vue utiliza el Proxyobjeto detrás de escena para lograrlo. También vimos cómo podemos crear objetos reactivos usando reactivey cómo crear propiedades reactivas usando ref.

    Finalmente, vimos cómo convertir objetos reactivos en objetos simples, cada una de cuyas propiedades apunta refa la propiedad correspondiente del objeto original, y vimos cómo crear una refpropiedad en un objeto fuente reactivo.

    Recursos adicionales

    • “ Proxy ” (objeto), MDN Web Docs
    • “ Fundamentos de reactividad ”, Vue.js
    • “ Referencias ”, Vue.js
    • “ Registro del gancho del ciclo de vida internosetup ”, Vue.js

    (ks, vf, yk, il, al)Explora más en

    • vista
    • javascript
    • Marcos





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Reactividad en Vue

    El método reactivoreftoRefstoRefConclusiónAccesibilidad para diseñadores, con Stéphanie Walter Creación y mantenimiento de sistemas de diseño exitosos,

    programar

    es

    2025-01-15

     

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Update cookies preferences