My Profile Photo

Jociel Souza

PHP Clojure Javascript Mongodb ZendFramework


Desenvolvedor Web - Backend - PHP


Estudante de Ciência da Computação, desenvolvedor de software apaixonado por tecnologia.


Estudante de Ciência da Computação procurando sempre aprender algo novo, desenvolvedor web com conhecimento em PHP7^, Zend Framework, Zend Expressive, Doctrine ORM, Doctrine ODM, MongoDB, Javascript, VueJS, HTML, GIT entre outros, atualmente estudando também Clojure, Elm e o paradigma funcional e tentando compartilhar o conhecimento adquirido.


Vue - Reatividade no VueJS 3.0 | Jociel Souza

Vue - Reatividade no VueJS 3.0

Diferença entre reactive, ref, toRef e toRefs


O VueJS na sua versão 3.0 mudou um pouco como definir a forma de reatividade do dados que são criados e utilizados nos componentes, vamos ver um pouco como está funcionando com essas mudanças.


Nate Grant em Unsplash


ES6 Proxy

O ES6 trouxe uma nova funcionalidade na linguagem chamada Proxy.

Também em Design Patterns em Orientação a Objetos temos um padrão chamado Proxy, esse padrão estrutural fornece uma interface de acesso, um controlador de acesso, um interceptor, a um objeto.

E é exatamente isso que essa nova funcionalidade nos fornece, uma maneira de adicionar um comportamento customizados ao acessar ou modificar um objeto. Duas das funções principais são get e set utilizadas para recuperar o valor de uma propriedade e alterar/definir uma propriedade e seu valor respectivamente.

const obj = {
    name: "Marcelo",
    age: 20
}

const objProxy = new Proxy(obj, {
    // target é o objeto original ao qual foi criado o proxy (obj)
    // propertie é a propriedade que estamos tentandop acessar (name ou age)
    get: (target, propertie) => {
        console.log(`Acessando a propriedade ${propertie}`)
        return target[propertie]
    },
    
    // target é o objeto original ao qual foi criado o proxy (obj)
    // propertie é a propriedade que estamos tentandop acessar (name ou age)
    // value é o novo valor que será atribuida a propriedade propertie
    set: (target, propertie, value) => {
        console.log(`Alterando o valor da propriedade ${propertie}`)
        target[propertie] = value
    }
})

As funções get e set serão executadas toda vez que tentarmos acessar ou alterar uma propriedade a partir do proxy criado, e podemos definir qualquer tipo de lógica para esse Proxy.

objProxy.name // Acessando a propriedade name Marcelo

objProxy.age = 25 // Alterando o valor da propriedade age 25

O funcionamento do Proxy do ES6 é a base do funcionamento da reatividade no Vue 3 implementada com algumas funções fornecidas pela Composition API do VueJS 3.0.


reactive

Utilizado quando precisamos adicionar reatividade em um objeto natural qualquer que tivermos, reactive cria um wrapper proxy para esse objeto, a partir dai podemos trabalhar apenas com o objeto proxy para termos um comportamento reativo.

import { reactive } from "vue"

const state = {
	userName: "Marcelo",
	userAge: 23
}
const stateProxy = reactive(state)

// OU

const statePx = reactive({
	userName: "Marcelo",
	userAge: 23
})

Desta forma o stateProxy estará com comportamento reativo e qualquer alteração dos dados será refletido onde for utilizado esse objeto, uma alteração feita pelo proxy resultará em uma alteração no objeto original.


ref

Cria um objeto ref com comportamento reativo a partir de um valor primitivo ou array, esse objeto tem um única propriedade chamada value que contém o valor definido, se um objeto for passado como valor, será criado um proxy com a função reactive e esse proxy será atribuído ao value da ref que criamos.

import { ref } from "vue"

const age = ref(23)

console.log(age.value) // 23
console.log(age)    // RefImpl {
                    //    __v_isRef: true
                    //    _rawValue: 23
                    //    _shallow: false
                    //    _value: 23
                    //    value: 23
                    //    __proto__: Object
                    // }

const state = ref({ age: 23 })
console.log(state.value)    // Proxy {
                            //		[[Handler]]: Object
                            //		[[Target]]: Object
                            //		   age: 23
                            //		__proto__: Object
                            //		[[IsRevoked]]: false
                            // }

console.log(state.value.age)    // 23


toRef

Podemos utilizar toRef para criar um ref a partir de uma propriedade de um objeto proxy reactive, ou seja, que foi criado com a função reactive, esse novo ref mantém a conexão com o proxy original, então caso haja uma alteração em qualquer um dos objetos essa alteração será refletida no outro objeto.

import { reactive, toRef } from "vue"

const objProxy = reactive({ userName: "Marcelo", userAge: 23 })

const userName = toRef(objProxy, "userName")
console.log(userName.value) // Marcelo
console.log(userName)   // ObjectRefImpl {
                        //	__v_isRef: true
                        //	_key: "userName"
                        //	_object: Proxy        - Referência ao objeto proxy de origem -
                        //		[[Handler]]: Object
                        //		[[Target]]: Object
                        //		[[IsRevoked]]: false
                        //	value: "Marcelo"
                        //	__proto__: Object
                        // }

userName.value = "João"
console.log(objProxy.userName)  // João


toRefs

toRefs é semelhante ao toRef, com toRefs podemos passar um objeto proxy rective e irá ser criado um objeto simples com cada propriedade existente do proxy sendo um ref.

Se aplicarmos destructuring a um proxy reactive perdemos a reatividade desses dados.

Mas utilizando toRefs podemos aplicar destructuring e manter a característica de reatividade dos dados.

import { reactive, toRefs } from "vue"

const objProxy = reactive({ userName: "Marcelo", userAge: 23 })

const refsObject = toRefs(objProxy)
console.log(refsObject) // {
                        //    userAge: ObjectRefImpl
                        //	    __v_isRef: true
                        //	    _key: "userAge"
                        //	    _object: Proxy {userName: "Marcelo", userAge: 23}
                        //	    value: 23
                        //
                        //    userName: ObjectRefImpl
                        //	    __v_isRef: true
                        //	    _key: "userName"
                        //	    _object: Proxy {userName: "Marcelo", userAge: 23}
                        //	    value: "Marcelo"
                        // }

const { userName, userAge } = toRefs(objProxy)
console.log(userName)   // ObjectRefImpl {
                        //	 __v_isRef: true
                        //	 _key: "userName"
                        //	 _object: Proxy {userName: "Marcelo", userAge: 23}
                        //	 value: "Marcelo"
                        // }

console.log(userAge)    // ObjectRefImpl {
                        //		__v_isRef: true
                        //		_key: "userAge"
                        //		_object: Proxy {userName: "Marcelo", userAge: 23}
                        //		value: 23
                        // }



Referências:
  • https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Proxy
  • https://v3.vuejs.org/api/basic-reactivity.html
  • https://v3.vuejs.org/api/refs-api.html
comments powered by Disqus