22 jan 2025
Helper Functions ou Composables? Quando criar cada um?
Uma dúvida que surgiu em um post meu recente foi: quando criar uma função helper/util e quando criar um composable?
Uma abordagem prática que sigo é:
- Se a função utiliza recursos específicos do Vue, como ref, computed, métodos do ciclo de vida, etc, eu crio um composable.
- Nenhum dos pontos citados acima: crio função “pura” js/ts que pode ser usada em qualquer lugar sem dependência de APIs específicas de framework. Geralmente utilizo a pasta helpers ou utils (nunca vi um consenso em relação a isso).
Essa distinção simplifica o processo de manutenção, uma vez que funções helpers podem ser reutilizadas em diferentes contextos ou frameworks, enquanto composables ficam focados em lidar com a reatividade e recursos específicos do Vue.
Exemplo prático:
Imagine que você precisa formatar um valor de data para pt-BR e exibir esse valor em um componente.
Podemos utilizar uma função que realiza a formatação da data. É independente de frameworks e pode ser usada em qualquer lugar. O problema: perdemos a reatividade do Vue. Isso não é necessariamente um problema, dependendo da arquitetura da solução.
// @/helpers/formatDate.ts
export function formatDate(date: Date) {
return new Intl.DateTimeFormat("pt-BR").format(date)
}
Ao criarmos um composable, conseguimos manter o sistema de reatividade. Isso abre brecha para trabalharmos com watchers, ciclos de vida do componente e mais.
// @/composables/useFormattedDate.ts
export function useFormattedDate(date: Ref<Date>) {
// toRef(date) ou toValue(date) se necessário
const formatted = computed(() => {
return new Intl.DateTimeFormat("pt-BR").format(date.value)
})
return { formatted }
}
Eu gosto de utilizar o máximo possível de funções “puras” para garantir que o código seja reaproveitado em diferentes contextos. Essa prática aumenta a flexibilidade do projeto e reduz o esforço de reescrita em outros ambientes.
Por outro lado, vejo nos composables uma uma forma de organizar e separar as features e lógicas do projeto que dependem diretamente do Vue. Como citei em outro post, gosto de seguir com a abordagem de “thin composables” para separar features.