Búsqueda de sitios web

typescript - Cómo pasar datos reactivos a un composable en Vue 3


¿Es posible declarar un objeto reactivo en Vue y luego pasar los miembros de ese objeto a un composable manteniendo la reactividad?

Por ejemplo:

Declaro un tipo "State":

type State = { myObjectList: Array<MyObject> }

Luego, en mi componente inicializo mi estado:

const state = reactive<State>{( myObjectList: new Array<MyObject>() )}

Dónde state.myObjectList se llena mediante una llamada a la API al montar el componente

Mi pregunta es, ¿es posible pasar state.myObjectList a un composable, y que ese composable sea consciente de los cambios realizados en los elementos dentro de state.myObjectList?

es decir, tener un componible como:

export default function useSimpleCalculator(list: Array<MyObject>){

  const dynamicSumValue = computed(():number => { 
    let sum = 0;
    list.forEach(el => {  sum += el.someValueThatChanges });
    return sum;
  });

 return { dynamicSumValue }

}

entonces usa ese componible así:

const {dynamicSumValue} = useSimpleCalculator(state.myObjectList);

y que dynamicSumValue se actualice a medida que se realicen cambios en los elementos dentro de state.myObjectList

He intentado implementar como lo anterior, pero cuando paso cualquier propiedad que estaba en el objeto state, pierde su reactividad dentro del composable.

Pasar refs al composable parece funcionar (es decir, const val=ref(2)), pero eso va en contra del patrón que nuestro equipo decidió para los datos de estado a nivel de componente

Cualquier información sería útil

Respuesta #1

Como has descubierto, no puedes pasar propiedades de un objeto reactivo a una función y mantener la reactividad de esa propiedad. Esto también ocurre a menudo con las props, que son simplemente un objeto reactivo como 'state' en tu ejemplo. Necesitarás convertir tu state en refs y pasar un ref para que la reactividad funcione correctamente:

useSimpleCalculator(toRef(state, 'myObjectList'));

o

const { myObjectList } = toRefs(state);
useSimpleCalculator(myObjectList)

ambos funcionarán

Respuesta #2

Los refs se usan específicamente en los casos en que un valor necesita ser pasado por referencia (de ahí el nombre).

Dado que list no se supone que debe modificarse, puede ser simplemente una referencia calculada:

const myObjectList = computed(() => state.myObjectList);
useSimpleCalculator(myObjectList);

y

function useSimpleCalculator(list: Ref<Array<MyObject>> | ComputedRef<Array<MyObject>>){...}

Artículos relacionados