Vue – @govbr-ds/webcomponents-vue
Este wrapper Vue encapsula os Web Components GovBR-DS, permitindo que sejam utilizados como componentes nativos no Vue.
Compatibilidade
- Vue
>=3.4.38 <4.0.0. @govbr-ds/webcomponents2.0.0.- Navegadores: a mesma política Baseline Widely Available dos Web Components. Internet Explorer não é suportado.
Essa faixa acompanha o peer exigido pelo runtime do output target Vue.
Por que usar este wrapper? 🤔
- Verificação de tipos.
- Integração com Vue Router.
- Suporte a
v-modelpara componentes de formulário.
Mais detalhes na documentação do Stencil.
Instalação 📦
npm install @govbr-ds/webcomponents-vue
# ou
pnpm add @govbr-ds/webcomponents-vue
# ou
yarn add @govbr-ds/webcomponents-vue
peerDependencies
peerDependencies são pacotes que este wrapper não instala automaticamente — o seu projeto precisa tê-los instalados.
Observe que algumas peerDependencies podem ter suas próprias peerDependencies que também precisam ser atendidas. Consulte a documentação de cada pacote para garantir que todas as dependências necessárias estejam presentes.
Por que existem: Garantem que o seu app Vue e o wrapper compartilhem a mesma instância do Vue e dos Web Components. Versões duplicadas causam erros em tempo de execução.
O que isso implica: Se as peers não estiverem instaladas ou forem incompatíveis, componentes podem não funcionar.
As peers declaradas neste pacote são:
| Pacote | Versão mínima |
|---|---|
vue | >=3.4.38 <4 |
@govbr-ds/webcomponents | ^2 |
Se você seguiu o comando de instalação acima, ambas as peers já estão incluídas.
Nota importante: pnpm e tree-shaking
Se ao consumir estes pacotes você notar que o bundler não está removendo código não utilizado (tree‑shaking), pode haver uma incompatibilidade com o layout padrão do pnpm.
Solução rápida (opcional, somente se precisar): crie um arquivo .npmrc na raiz do seu projeto com:
node-linker=hoisted
Por que isso ajuda: por padrão, o pnpm organiza as dependências em pastas isoladas com symlinks. Alguns bundlers/otimizadores se baseiam na estrutura de node_modules e no campo sideEffects para decidir o que pode ser eliminado. O layout hoisted aproxima o formato “achatado” (similar ao npm/yarn), facilitando essa análise e, em muitos casos, restaurando o tree‑shaking.
Observações:
- Use apenas se o tree‑shaking realmente não estiver funcionando.
- Pode aumentar o uso de disco e alterar a resolução de dependências do seu projeto.
Quickstart Vue
Use o quickstart Vue como referência para configuração de projeto:
- Repositório: govbr-ds-wbc-quickstart-vue
- Servidor local:
pnpm dev - Porta padrão:
http://localhost:5173/
Uso 📚
Configuração do template (Vite)
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.includes('br-'),
},
},
}),
],
})
Uso com componentes
import { BrButton } from '@govbr-ds/webcomponents-vue'
Uso com v-model:
<script setup lang="ts">
import { ref } from 'vue'
const name = ref('Lorem ipsum')
</script>
<template>
<h1>Olá {{ name }}</h1>
<br-input name="name" placeholder="Seu nome" v-model="name" />
</template>
Validação e Acessibilidade (VeeValidate / nativo)
A validação de campos pode ser implementada reativamente, repassando o estado de erro (state="danger") para o componente <br-input> ou similares. O wrapper do Vue repassa as propriedades reativas de forma eficiente, garantindo a atualização do DOM e comunicação aos leitores de tela por meio de aria-invalid.
<script setup lang="ts">
import { ref, computed } from 'vue'
const email = ref('')
const emailError = computed(() => {
if (!email.value) return 'O e-mail é obrigatório'
if (!email.value.includes('@')) return 'E-mail inválido'
return ''
})
const showErrors = ref(false)
function submit() {
showErrors.value = true
if (!emailError.value) {
// submeter formulário
}
}
</script>
<template>
<form @submit.prevent="submit">
<br-input
label="E-mail"
v-model="email"
:state="showErrors && emailError ? 'danger' : 'info'"
/>
<br-message v-if="showErrors && emailError" state="danger" show-icon>
{{ emailError }}
</br-message>
<br-button type="submit">Enviar</br-button>
</form>
</template>
Dependências de Build 🛠️
Este pacote é um wrapper gerado automaticamente e depende dos artefatos produzidos pelo núcleo de Web Components.
| Pacote | Dependência de Build | Motivo |
|---|---|---|
@govbr-ds/webcomponents-vue | webcomponents:build | Necessita dos proxies gerados em src/stencil-generated. |
Desenvolvimento 👨💻
Estrutura do projeto
├── 📁 src
│ ├── 📁 stencil-generated
│ └── 📄 index.ts
[!WARNING] Tudo dentro de
stencil-generatedé sobrescrito ao gerar o build de Web Components.
Scripts/Build
nx build webcomponents
nx build vue
Gerenciar baseline de tamanho:
# Da raiz do monorepo:
pnpm run baseline:update # Atualizar todas as baselines
pnpm run baseline:compare # Comparar todas as baselines
Nuxt 3
Para Nuxt 3, configure vue.compilerOptions em nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('br-'),
},
},
})
Use o plugin defineNuxtPlugin para registrar os Web Components apenas no cliente:
// plugins/govbr-ds.client.ts
import { defineCustomElements } from '@govbr-ds/webcomponents/loader'
export default defineNuxtPlugin(() => {
defineCustomElements()
})
Formatos do build 📦
A tarefa nx build vue compila o wrapper e gera a saída em dist/vue/. Abaixo estão os artefatos produzidos e quando utilizá-los.
Estrutura do dist/vue/
dist/vue/
├── src/
│ ├── index.js ← Entrada principal (ESM)
│ ├── index.d.ts ← Tipos TypeScript
│ └── stencil-generated/
│ └── components.js ← Componentes proxy com v-model (gerados pelo Stencil)
├── package.json
└── README.md
Quando usar cada formato
| Artefato | Quando usar | Observações |
|---|---|---|
src/index.js | Aplicações Vue 3 (Vite, Webpack, Nuxt) | Importação padrão via @govbr-ds/webcomponents-vue |
src/index.d.ts | Autocomplete e tipagem TypeScript | Resolvido automaticamente pelo campo types do package.json |
v-model e componentModels
Os componentes de formulário suportam v-model nativamente graças à configuração componentModels do Stencil Vue output target. Isso significa que:
br-input,br-select,br-checkbox,br-radioe outros componentes de formulário emitem o evento correto e expõem a prop adequada para two-way binding.- Não é necessário configuração extra — use
v-modeldiretamente:
<script setup lang="ts">
import { ref } from 'vue'
import { BrInput } from '@govbr-ds/webcomponents-vue'
const nome = ref('')
</script>
<template>
<BrInput v-model="nome" label="Nome" />
</template>
Documentações Complementares 📖
- Wiki: gov.br/ds/wiki/desenvolvimento/web-components
- MDN Web Components: developer.mozilla.org/Web_Components
Contribuindo 🤝
- Padrões e boas práticas: gov.br/ds/wiki
- Como contribuir: contribuindo com o DS
Reportar Bugs/Problemas 🐛
Abra uma issue: gitlab.com/.../issues/new
Commits 📝
Padrões de branches e commits: gov.br/ds/wiki
Precisa de ajuda? 🆘
- Site: gov.br/ds
- Web Components: gov.br/ds/webcomponents
- Discord: discord.gg/U5GwPfqhUP
Créditos 🎉
Desenvolvido pelo SERPRO com a comunidade.