Skip to content

Exemplos e vídeos por funcionalidade ​

Estes clipes foram gravados no app de e-mail NativeScript-Vue de demo/, em simuladores iOS 26 e iPadOS 26 e um emulador Android 16. O guia de cada funcionalidade inclui sua gravação junto do código. O app usa mensagens de exemplo locais; não se conecta a um serviço de e-mail.

Os clipes não têm áudio, repetem enquanto estão visíveis e têm controles de reprodução. Com Reduzir Movimento ativado, esperam você dar play.

Escolha uma funcionalidade, veja o resultado e copie o trecho correspondente. Os exemplos usam componentes NativeScript e a tabela de rotas do demo. Em páginas roteadas, obtenha router com useRouter() no <script setup>; na configuração do app, use a instância criada com createRouter(). Importe os componentes do router de vue-router-ns. Os trechos de template entram no componente indicado, não substituem a configuração inicial do app.

Instalação · Transição a partir de um elemento · Demo completo

Abrir uma página a partir de um card ​

O card abre a mensagem com o zoom do UIKit e recebe a transição de volta. Simulador iOS 26.

O elemento tocado pode ser a origem do zoom nativo do UIKit. Use um único filho em RouterLink; no Android e em runtimes sem a API de zoom, a navegação usa a transição normal.

vue
<RouterLink :to="{ name: 'message', params: { id: 1 } }" zoom>
  <StackLayout padding="24" borderRadius="16" backgroundColor="#dbeafe">
    <Label text="Ana" color="#1e3a8a" />
    <Label text="Lunch on Friday?" color="#1e3a8a" />
  </StackLayout>
</RouterLink>

Exemplo completo: card, lista com zoomFrom, destino e rotas. O zoom requer iOS 18+ e suporte do runtime. No demo, abra Settings → Zoom from a card.

Abas com históricos independentes ​

Abra uma mensagem, troque de aba e volte para a mesma mensagem. Toque na aba selecionada novamente para voltar à raiz. Configure as abas nativas.

Abas do UIKit no iPhone, incluindo o retorno à raiz ao selecionar de novo.
A mesma navegação com abas do Material no Android.
A sidebar do UIKit seleciona as mesmas pilhas nomeadas no iPad.
vue
<RouterTabs sidebar>
  <RouterTab name="inbox" title="Inbox" icon="tray.fill">
    <RouterView name="inbox" initial="/" backToRootOnReselect />
  </RouterTab>
  <RouterTab name="settings" title="Settings" icon="gearshape.fill">
    <RouterView name="settings" initial="/settings" backToRootOnReselect />
  </RouterTab>
</RouterTabs>

No componente raiz do app. sidebar habilita a sidebar no iPad; cada RouterView mantém sua própria pilha. Navegar com { frame: 'settings' } também seleciona essa aba. Código completo.

Push, voltar e lista/detalhe ​

O caminho no rodapé é a pilha do router ao vivo. Abrir outra mensagem adiciona uma entrada; Back to inbox remove os detalhes em uma navegação. Uma janela larga mantém a lista visível. Navegação · Lista e detalhe.

Abra duas mensagens e volte à caixa de entrada no iPhone.
Abra mensagens no painel de detalhes enquanto a caixa de entrada continua visível no iPad.
ts
await router.push({ name: 'message', params: { id: 1 } })
await router.push({ name: 'message', params: { id: 2 } })
await router.backToRoot()

Em uma janela larga, substitua o RouterView da caixa de entrada por:

vue
<RouterSplitView name="inbox" list="/" :breakpoint="840" :listWidth="320" />

Abaixo do breakpoint, lista e detalhe usam a navegação de uma coluna. Acima dele, a lista fica visível ao abrir detalhes. Código completo.

Sheets nas duas plataformas ​

Compose usa uma sheet do UIKit com detents no iOS e uma bottom sheet do Material no Android. Ambas contêm uma página roteada com sua própria barra de navegação nativa. Modais e resultados.

Abra, expanda e feche a sheet de composição no iPhone.
Abra a sheet do Material e feche com o Voltar do sistema.
ts
router.push('/compose', {
  modal: {
    ios: { detents: ['medium', 'large'], grabber: true },
    android: { sheet: { state: 'expanded', height: 520 } },
  },
})

Toque em Compose, arraste a sheet e feche com Cancel ou Voltar. Adicione Material ao build de release Android, como descrito no guia. Código completo.

Prévia antes de navegar ​

Uma pressão longa mostra a prévia da mensagem e suas ações. Tocar na prévia abre a rota. Menus de contexto.

A prévia nativa do UIKit e a página da mensagem aberta a partir dela.
vue
<RouterLink to="/messages/1" :menu="{ preview: MessagePreview, props: { id: 1 } }">
  <Label text="Lunch on Friday?" padding="24" />
</RouterLink>

Importe MessagePreview de demo/src/components/MessagePreview.vue. A prévia não adiciona uma página à pilha; tocar nela confirma a navegação. No Android, as mesmas opções abrem um menu, sem prévia ao vivo. Código completo.

Guards e restauração de formulário ​

Account exige uma sessão. O guard redireciona para o login, e digitar um nome ativa um guard de saída. No Android, esse formulário também pode sobreviver ao encerramento do processo em segundo plano. Guards · Restauração.

Stay mantém o nome digitado; Leave permite fechar a página.
Digite um nome, coloque o demo em segundo plano, encerre seu processo e reabra com o formulário restaurado.
ts
import { Dialogs } from '@nativescript/core'
import { ref } from 'nativescript-vue'
import { onBeforeRouteLeave, usePageState } from 'vue-router-ns'

const name = ref('')
onBeforeRouteLeave(() => Dialogs.confirm('Discard this draft?'), {
  when: () => name.value.trim() !== '',
})
usePageState<{ name: string }>('form', {
  save: () => ({ name: name.value }),
  restore: (saved) => {
    name.value = saved.name
  },
})

Vincule name a um <TextField v-model="name" />. Para persistir após o encerramento do processo, configure também restore.save e restore.load. O guard de autenticação fica em demo/src/router.ts. Código completo.

Busca e drawer nativos ​

A busca filtra a página atual sem adicionar rotas. O drawer do Android usa a política de links do router para abrir destinos e fecha antes que uma página saia da pilha. Busca nativa · Drawer.

A página controla seu campo de busca nativo e a consulta.
Selecione Settings pelo drawer e depois feche o drawer com o Voltar do sistema.
ts
import { computed, ref } from 'nativescript-vue'
import { useNativeSearch } from 'vue-router-ns'

const query = ref('')
const messages = [{ subject: 'Lunch on Friday?' }, { subject: 'Release notes' }]
const search = useNativeSearch({ query, placeholder: 'Search messages' })
const filtered = computed(() =>
  messages.filter((message) =>
    message.subject.toLowerCase().includes(query.value.toLowerCase()),
  ),
)

Use filtered como :items de um ListView e chame search.activate() em um ActionItem. Para o drawer, no componente raiz, declare const menuOpen = ref(false) e use um botão para alterná-lo:

vue
<RouterDrawer v-model:open="menuOpen">
  <template #drawer>
    <StackLayout>
      <Button text="Inbox" @tap="router.push('/')" />
      <Button text="Settings" @tap="router.push('/settings')" />
    </StackLayout>
  </template>
  <RouterView />
</RouterDrawer>

Este exemplo mínimo tem uma pilha. O demo completo combina drawer e abas; no iOS o conteúdo continua visível e o drawer é omitido. Código completo.

Escolha as convenções por arquivos ​

O exemplo separado de coleção usa rotas geradas, layout nativo, middleware de autenticação e modal com resultado tipado. Os dois estilos usam o mesmo router nativo. Configuração opcional e código.

Rotas geradas no iOS: detalhe, resultado de modal e conta protegida.
O mesmo fluxo da coleção em Pages nativas no Android.
text
src/pages/
  index.vue          → /
  messages/[id].vue  → /messages/:id
  compose.vue        → /compose

Escolha o plugin de webpack ou Vite para gerar essa tabela. Os exemplos de layouts e middleware mostram como adicionar convenções; declarar routes em TypeScript continua sendo uma opção independente. Código completo.

Receber um resultado de outra página ​

Reply abre o modal; Send devolve o texto à mensagem de origem com pushForResult. Simulador iOS 26.

Abra Reply em uma mensagem. Ao enviar, a resposta aparece na página que abriu o modal.

ts
import { ref } from 'nativescript-vue'
import { useRouter } from 'vue-router-ns'

const router = useRouter()
const reply = ref<string>()
async function compose() {
  reply.value = await router.pushForResult<string>('/compose')
}

Na página Compose, chame router.back({ result: text.value }). Fechar sem enviar resolve com undefined. O tipo descreve o contrato entre as páginas. Guia · Código completo.

O sistema entrega vuerouterns://settings/account. Settings é selecionada e o guard abre o login. Simulador iOS 26.

Na configuração do app, use os mesmos nomes de pilha de RouterTabs.

ts
const router = createRouter({
  routes,
  links: {
    schemes: ['https', 'vuerouterns'],
    hosts: ['vue-router-ns.rafaelaugusto.dev'],
    frame: (to) => (to.path.startsWith('/settings') ? 'settings' : 'inbox'),
  },
})

await router.openLink('vuerouterns://messages/1')

Teste também vuerouterns://settings/account sem sessão: o guard deve abrir o login na aba Settings. Para entregar URLs pelo sistema, configure o scheme/associação de domínio nativos; openLink() testa o encaminhamento dentro do app. Configuração e exemplos de notificações.

Atalhos no ícone do aplicativo ​

Pressione o ícone do demo e escolha New message para abrir a rota pelo atalho nativo. Simulador iOS 26.

Publique os destinos depois que o app estiver pronto, como em demo/src/app.ts.

ts
router.setShortcuts([
  {
    id: 'compose',
    title: 'New message',
    to: '/compose',
    icon: { ios: 'square.and.pencil' },
  },
  { id: 'settings', title: 'Settings', to: '/settings' },
])

Pressione o ícone do app no launcher/SpringBoard e escolha New message. A rota passa pelos mesmos guards. Use setShortcuts([]) para remover atalhos dinâmicos ao sair da conta. Limites e atalhos fixados.

Anexar um documento do sistema ​

Attach abre o seletor de documentos do iOS. Cancelar retorna ao formulário com Picker cancelled, sem adicionar uma rota.

No setup de uma página roteada, prepare o picker e chame attach() pelo botão Anexar.

ts
import { ref } from 'nativescript-vue'
import { createDocumentPicker, useNativeFlow } from 'vue-router-ns'

const attachments = ref<string[]>([])
const picker = useNativeFlow(createDocumentPicker())
async function attach() {
  const outcome = await picker.run({ types: ['application/pdf'], multiple: true })
  if (outcome.status === 'completed') attachments.value = outcome.value.uris
  else if (outcome.status === 'failed') console.error(outcome.error)
}

Escolha um PDF ou cancele. A página permanece na mesma entrada do histórico; cancelar mantém a seleção anterior. URIs não garantem permissão permanente: leitura e persistência de acesso pertencem ao app. Picker completo e ciclo de vida.

Devolver o foco ao botão que abriu o modal ​

Com VoiceOver ou TalkBack ativado, abra e feche Reply. O foco deve retornar ao botão de origem.

ts
import { useNavigationFocus, useRouter } from 'vue-router-ns'

const router = useRouter()
const focus = useNavigationFocus({ initial: 'heading', return: 'reply' })
async function reply() {
  focus.remember('reply')
  await router.pushForResult('/compose')
}
vue
<Label id="heading" text="Message" accessible="true" />
<Button id="reply" text="Reply" @tap="reply" />

Coloque os controles dentro da página. O foco é de acessibilidade, não de teclado. O padrão motion: 'system' respeita movimento reduzido. Exemplo completo e limites.

Reconstruir uma pilha com retorno previsível ​

Use uma lista de destinos quando a entrada do usuário exigir um histórico específico.

ts
await router.setStack(['/', '/messages/1', '/messages/2'])
await router.back()
await router.backToRoot({ animated: false })

Depois de setStack, Voltar abre a mensagem 1; o último comando retorna à caixa de entrada sem animação. Guards podem interromper a sequência, e etapas já concluídas permanecem. Definindo a pilha.

Mais exemplos completos ​

Os vídeos são gravações de navegação nativa. O exemplo de foco inclui passos para VoiceOver/TalkBack: um vídeo sem áudio não demonstra o anúncio do leitor de tela.

Rode o mesmo app ​

Instale a CLI do NativeScript e compile o router local a partir da raiz do repositório:

sh
npm install
npm run build
cd demo
npm install
ns run ios
# ou: ns run android

O demo resolve vue-router-ns pelo diretório dist local. Use npm run dev em outro terminal enquanto altera o router. Veja no README do demo as APIs usadas por cada página.

Publicado sob a licença MIT.