07 nov 2024
Conhecendo o defineExpose no Vue
No Vue, temos um macro pouco conhecido chamado defineExpose
, que serve para expor métodos e propriedades públicas de componentes aos seus componentes pai. Esse macro permite definir quais partes do componente podem ser acessadas publicamente.
O uso defineExpose
serve para facilitar o compartilhamento de dados e métodos entre componentes. Ele permite que um componente filho exponha ref ou funções ao pai, aumentando a comunicação entre eles.
- Dentro do componente filho (ComponentB.vue)
<script setup lang="ts">
const title = ref("")
defineExpose({ title })
</script>
<template>
<input type="text" v-model="title" />
</template>
- No componente pai (ComponentA)
<script setup lang="ts">
import ComponentB from "./ComponentB.vue"
const insideValueTitle = ref<InstanceType<typeof ComponentB> | null>(null)
</script>
<template>
<div>
<h2>The title is: {{ insideValueTitle?.title }}</h2>
<ComponentB ref="insideValueTitle" />
</div>
</template>
No exemplo do código acima, o ComponentB expõe a propriedade title ao componente pai (ComponentA), que consegue acessar (e modificar) diretamente esse valor, mantendo a reatividade. Dessa forma, reduzimos a necessidade de emissão de eventos, por exemplo.
Tá, mas e o defineModel
? Ambos não fazerm a mesma coisa?
Enquanto o defineExpose
é utilizado somente para tornar propriedades e métodos de um componente acessíveis para o componente pai. Em outras palavras: para gerenciamento e sincronização de estado reativo, use o defineModel
. Se precisar ler alguma propriedade pontualmente (mantendo a reatividade) ou acessar algum método interno, o defineExpose
pode ser uma boa solução.
Um outro caso de uso (o que me fez descobrir o defineExpose
) é passar uma template ref de um elemento interno para ser lidado no componente acima. Por exemplo: podemos passar uma template ref de um input e realizar o foco direto pelo componente pai após algum método ser executado. As possibilidades são imensas.