Escrevi este tutorial detalhado passo a passo para que qualquer pessoa possa criar seu próprio aplicativo usando a estrutura Nuxt.js do zero.
Neste artigo, discutiremos os fundamentos, os fundamentos da criação de um aplicativo Nuxt.js:
- criação e configuração do projeto,
- ativos e estáticos: estilos, fontes, imagens, postagens,
- criando componentes,
- criando páginas e layouts,
- implantação de aplicativos (implantação).
Veja o que aconteceu!
Um pouco sobre o Nuxt.js
Nuxt é uma estrutura Vue de alto nível. O Nuxt.js permite que você desenvolva aplicativos da Web isomórficos prontos para uso, abstraindo os detalhes de distribuição do código do servidor e do cliente. Graças a essa abordagem, economizamos tempo e podemos nos concentrar no desenvolvimento.
As principais vantagens do Nuxt:
- SPA, SSR e pré-renderização já estão configurados; tudo o que é exigido de nós é indicar. Neste aplicativo, utilizamos um pré-renderizador para o modo de produto, ou seja, geraremos todas as páginas do site antecipadamente, e a seguir implantamos no hosting para distribuição de estática.
- Um ótimo SEO para todos os mecanismos de pesquisa é o resultado do uso de SSR ou pré-renderizador.
- . js chunks, css styles API ( webpack 4, Nuxt).
- Google Lighthouse / Page Speed. 100/100 .
- CSS Modules, Babel, Postscc create-nuxt-app.
- .
- 50 Vue.js.
Podemos falar sobre os benefícios do Nuxt por muito tempo. Esta é a estrutura que eu realmente amo por sua facilidade de uso e capacidade de criar aplicativos flexíveis e facilmente escaláveis. Então, proponho começar e ver todos os benefícios na prática.
Mais informações sobre Nuxt.js no site oficial . Guias detalhados também estão disponíveis aqui .
Projeto
Um design bem pensado e pronto, ou ainda melhor um kit de IU, irá acelerar e simplificar significativamente o desenvolvimento de qualquer aplicativo. Se não houver um designer de IU gratuito por perto, tudo bem. Como parte de nossas instruções, podemos cuidar disso sozinhos!
Especialmente para este artigo, preparei um design de blog em um estilo moderno e minimalista com funcionalidade simples, o suficiente para demonstrar as capacidades do Nuxt.
Para o desenvolvimento, usei o serviço online Figma. O design e o kit de IU estão disponíveis aqui . Você pode copiar este modelo e usá-lo em seu projeto.
Criação de projeto
Para criar um projeto, usaremos o utilitário Nuxt create-nuxt-app dos desenvolvedores Nuxt , que nos permite configurar o modelo de aplicativo por meio do cli.
Inicializamos o projeto especificando seu nome:
npx create-nuxt-app nuxt-blog
Além disso, em vários estágios, o utilitário nos oferecerá a escolha de um conjunto de bibliotecas e pacotes preferidos, após o que ele os baixará, configurará e configurará independentemente para o projeto.
Você pode ver uma lista completa das opções selecionadas no Github .
Para este projeto será utilizada a configuração com Typescript.
Ao desenvolver no Vue com Typescript, você pode usar duas APIs: API de opções ou API de classe .
Eles não diferem funcionalmente um do outro, mas têm sintaxe diferente. Pessoalmente, a sintaxe da API de opções está mais próxima de mim, por isso será usada em nosso projeto.
Depois de criar o projeto, podemos executar nosso aplicativo usando o comando: npm run dev. Ele agora estará disponível em localhost: 3000.
Nuxt usa webpack-dev-server com HMR instalado e configurado como um servidor local , o que torna o desenvolvimento rápido e confortável.
Como estamos criando uma versão demo do aplicativo, não irei escrever testes para ele. Mas eu recomendo fortemente não negligenciar o teste de aplicativos no desenvolvimento comercial.
Se você não tocou neste tópico antes, aconselho que preste atenção a Jest - uma ferramenta muito simples, mas ao mesmo tempo poderosa que suporta o trabalho com Nuxt em conjunto com vue-test-utils .
Estrutura do projeto
O Nuxt cria por padrão um diretório e uma estrutura de arquivos adequados para um início rápido de desenvolvimento. Para o nosso projeto, essa estrutura se encaixa perfeitamente, então não vamos mudá-la. Você pode ler mais sobre a finalidade dos diferentes diretórios no site da Nuxt .
-- Assets
-- Static
-- Pages
-- Middleware
-- Components
-- Layouts
-- Plugins
-- Store
-- nuxt.config.js
-- ...other files
Criação de aplicativo
Antes de escrever o código, vamos fazer o seguinte:
1. Remova os componentes iniciais e as páginas geradas pelo Nuxt.
2. Instale o pug e o scss para nossa conveniência e para economizar tempo durante o desenvolvimento. Vamos executar o comando:
npm i --save-dev pug pug-plain-loader node-sass sass-loader fibers
Depois disso, o uso do atributo lang para as tags de modelo e estilo estará disponível:
<template lang="pug"></template>
<style lang="scss"></style>
3. Adicione suporte para o seletor :: v-deep à configuração do stylelint, o que permitirá estilizar os componentes filhos, ignorando o escopo. Você pode ler mais sobre este seletor aqui.
{
rules: {
'at-rule-no-unknown': null,
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep'],
},
],
},
}
Todos os preparativos acabaram, vá para a próxima fase.
Postagens
As postagens serão armazenadas no diretório content / posts, que criaremos na raiz do projeto como um conjunto de arquivos markdown.
Vamos criar 5 pequenos arquivos para que possamos começar a trabalhar com eles imediatamente. Para simplificar, usaremos os nomes 1.md, 2.md, etc.
No diretório de conteúdo, crie o arquivo Posts.d.ts, no qual definimos os tipos do objeto que contém todas as informações necessárias sobre a postagem:
export type Post = {
id: number
title: string
desc: string
file: string
img: string
}
Acho que o significado de todos os campos deve ficar claro a partir dos nomes.
Ir em frente. No mesmo diretório, crie outro arquivo chamado posts.ts com o seguinte conteúdo:
import { Post } from './Post'
export default [
{
id: 1,
title: 'Post 1',
desc:
'A short description of the post to keep the user interested.' +
' Description can be of different lengths, blocks are aligned' +
' to the height of the block with the longest description',
file: 'content/posts/1.md',
img: 'assets/images/1.svg',
},
...
{
id: 5,
title: 'Post 5',
desc:
'A short description of the post to keep the user interested.' +
' Description can be of different lengths, blocks are aligned' +
' to the height of the block with the longest description',
file: 'content/posts/5.md',
img: 'assets/images/5.svg',
},
] as Post[]
Na propriedade img, nos referimos a imagens no diretório assets / images, mas ainda não criamos esse diretório, vamos fazer isso agora.
Agora vamos adicionar as imagens no formato .svg ao diretório criado com os nomes que especificamos acima.
Vou tirar 5 imagens do unDraw . Este excelente recurso é constantemente atualizado e contém muitas imagens SVG gratuitas.
Agora que tudo está pronto, o diretório de conteúdo deve ficar assim: E o subdiretório de imagens deve aparecer no diretório de ativos com o seguinte conteúdo:
content/
-- posts.ts
-- Posts.d.ts
-- posts/
---- 1.md
---- 2.md
---- 3.md
---- 4.md
---- 5.md
assets/
-- images/
---- 1.svg
---- 2.svg
---- 3.svg
---- 4.svg
---- 5.svg
...
Recuperando arquivos dinamicamente
Como receberemos imagens e arquivos com o texto das postagens de forma dinâmica, precisamos implementar um mixin global, que possamos usar posteriormente em todos os componentes.
Para fazer isso, crie um subdiretório mixins no diretório de plug-ins e nele um arquivo getDynamicFile.ts com o seguinte conteúdo:
import Vue from 'vue'
export const methods = {
getDynamicFile(name: string) {
return require(`@/${name}`)
},
}
Vue.mixin({
methods,
})
Tudo o que nos resta é habilitar este mixin no arquivo nuxt.config.js:
{
plugins: [
'~plugins/mixins/getDynamicFile.ts',
],
}
Fontes
Após a fase de criação de postagens, conecte as fontes. A maneira mais fácil de fazer isso é a maravilhosa biblioteca Webfontloader , que permite obter qualquer fonte do Google Fonts . No entanto, no desenvolvimento comercial, as fontes personalizadas são freqüentemente usadas, então vamos examinar apenas esse caso aqui.
Rubik foi escolhida como a fonte de nosso aplicativo, que é distribuído sob a licença Open Font . Você pode baixar tudo nas mesmas fontes do Google .
Observe que no arquivo baixado as fontes estarão no formato otf, mas como trabalhamos com a web, os formatos woff e woff2 serão a melhor escolha para nós. Eles são menores do que quaisquer outros formatos, mas são perfeitamente suportados em todos os navegadores modernos. Para converter otf para os formatos de que precisamos, você pode usar um dos muitos serviços online gratuitos.
Portanto, temos as fontes nos formatos que precisamos, é hora de incluí-las no projeto. Para fazer isso, crie um subdiretório de fontes no diretório estático e adicione nossas fontes lá. Vamos criar um arquivo fonts.css no mesmo diretório, que será responsável por conectar nossas fontes na aplicação com o seguinte conteúdo:
@font-face {
font-family: "Rubik-Regular";
font-weight: normal;
font-style: normal;
font-display: swap;
src:
local("Rubik"),
local("Rubik-Regular"),
local("Rubik Regular"),
url("/fonts/Rubik-Regular.woff2") format("woff2"),
url("/fonts/Rubik-Regular.woff") format("woff");
}
...
O conteúdo completo do arquivo pode ser visto no repositório .
Há 2 coisas que vale a pena notar:
1. Especificamos font-display: swap ;, definindo como a fonte conectada via font-face será exibida dependendo se está carregada e pronta para uso.
Nesse caso, não definimos o período de bloqueio e definimos um período de substituição infinito. Ou seja, o carregamento da fonte ocorre em segundo plano e não bloqueia o carregamento da página, e a fonte será exibida quando estiver pronta.
2. Em src, especificamos a ordem de inicialização por prioridade. Primeiro, verificamos se a fonte desejada está instalada no dispositivo do usuário, verificando as possíveis variantes do nome da fonte. Se não o encontrarmos, verificamos se o navegador é compatível com o formato woff2 mais moderno e, caso não seja, passamos para o próximo formato woff. Existe a possibilidade de o usuário estar utilizando um navegador desatualizado (por exemplo, IE <9), neste caso, a seguir, indicaremos as fontes integradas ao navegador como fallback.
Depois de criar o arquivo com as regras de carregamento de fontes, você precisa conectá-lo ao aplicativo - no arquivo nuxt.config.js na seção head:
{
head: {
link: [
{
as: 'style',
rel: 'stylesheet preload prefetch',
href: '/fonts/fonts.css',
},
],
},
}
Observe que aqui, como antes, estamos usando as propriedades de pré-carregamento e pré-busca, definindo assim uma alta prioridade no navegador para baixar esses arquivos e não bloquear a renderização da página.
Vamos adicionar imediatamente ao diretório favicon estático de nosso aplicativo, que pode ser gerado usando qualquer serviço online gratuito.
O diretório estático agora se parece com isto: Passe para a próxima etapa.
static/
-- fonts/
---- fonts.css
---- Rubik-Bold.woff2
---- Rubik-Bold.woff
---- Rubik-Medium.woff2
---- Rubik-Medium.woff
---- Rubik-Regular.woff2
---- Rubik-Regular.woff
-- favicon.ico
Estilos reutilizáveis
Em nosso projeto, todos os estilos usados são descritos por um único conjunto de regras, o que torna o desenvolvimento muito mais fácil, então vamos transferir esses estilos do Figma para os arquivos do projeto.
No diretório de ativos, crie um subdiretório de estilos, no qual armazenaremos todos os estilos reutilizados no projeto. Por sua vez, o diretório de estilos conterá o arquivo variables.scss com todas as nossas variáveis scss.
O conteúdo do arquivo pode ser visto no repositório .
Agora precisamos conectar essas variáveis ao projeto para que estejam disponíveis em qualquer um de nossos componentes. Nuxt usa o módulo @ nuxtjs / style-resources para este propósito .
Vamos instalar este módulo:
npm i @nuxtjs/style-resources
E adicione as seguintes linhas a nuxt.config.js:
{
modules: [
'@nuxtjs/style-resources',
],
styleResources: {
scss: ['./assets/styles/variables.scss'],
},
}
Multar! As variáveis deste arquivo estarão disponíveis em qualquer componente.
A próxima etapa é criar algumas classes auxiliares e estilos globais que serão usados em todo o aplicativo. Essa abordagem permitirá que você gerencie de forma centralizada os estilos comuns e adapte rapidamente o aplicativo se a aparência dos layouts for alterada pelo designer.
Vamos criar um subdiretório global no diretório assets / styles com os seguintes arquivos:
1. typography.scss - o arquivo conterá todas as classes auxiliares para texto, incluindo links.
Observe que essas classes auxiliares mudam de estilo dependendo da resolução do dispositivo do usuário: smartphone ou PC.
2. transitions.scss - o arquivo conterá estilos de animação globais, tanto para transições entre páginas quanto para animações dentro de componentes, se precisarmos deles no futuro.
3. other.scss - o arquivo conterá estilos globais, que ainda não foram selecionados em um grupo separado.
A classe .page será usada como um contêiner comum para todos os componentes da página e formará o preenchimento correto na página.
A classe .section será usada para marcar os limites das caixas lógicas e a classe .content será usada para restringir a largura do conteúdo e centralizá-lo na página.
Veremos exemplos de como essas classes são usadas posteriormente, quando começarmos a implementar componentes e páginas.
4. index.scss - um arquivo geral que será usado como um único ponto de exportação para todos os estilos globais.
O conteúdo completo dos arquivos pode ser visto no Github .
Nesta fase, incluiremos esses estilos globais para que fiquem disponíveis em todo o aplicativo. Para esta tarefa, a Nuxt fornece uma seção css no arquivo nuxt.config.js:
{
css: ['~assets/styles/global'],
}
Vale a pena dizer que, no futuro, ao atribuir classes css, a seguinte lógica será usada:
1. Se um tag tiver classes auxiliares e classes locais, as classes locais serão adicionadas diretamente ao tag, por exemplo, p .algumas classes locais e as classes auxiliares são especificadas na propriedade da classe, por exemplo, class = "body3 medium".
2. Se uma tag tiver apenas classes auxiliares ou apenas classes locais, elas serão adicionadas diretamente à tag.
Eu uso essa técnica para minha conveniência, para distinguir visualmente imediatamente entre classes globais e locais.
Antes do desenvolvimento, vamos instalar e habilitar reset.css para que nosso layout pareça o mesmo em todos os navegadores. Para fazer isso, instale o pacote necessário:
npm i reset-css
E vamos incluí-lo no arquivo nuxt.config.js na seção css já familiar, que agora terá a seguinte aparência:
{
css: [
'~assets/styles/global',
'reset-css/reset.css',
],
}
Ocorrido? Em caso afirmativo, estamos prontos para avançar para a próxima etapa!
Layouts
No Nuxt, os Layouts são wrappers sobre as páginas que permitem reutilizar componentes comuns entre eles e implementar a lógica comum necessária. Como nosso aplicativo é extremamente simples, será suficiente usar o layout padrão - default.vue.
Além disso, o Nuxt usa um layout separado para uma página de erro como 404, que na verdade é uma página simples.
Layouts no repositório .
default.vue
Nosso default.vue não terá lógica e se parecerá com isto:
<template lang="pug">
div
nuxt
db-footer
</template>
Aqui usamos 2 componentes:
1. nuxt - durante a montagem, ele será substituído por uma página específica solicitada pelo usuário.
2.db-footer é nosso próprio componente Footer (vamos escrever um pouco mais tarde) que será adicionado automaticamente a todas as páginas de nosso aplicativo.
error.vue
Por padrão, para qualquer erro retornado do servidor no status http, o Nuxt redireciona para layout / error.vue e passa um objeto contendo uma descrição do erro recebido através de um parâmetro de entrada chamado error.
Vamos ver como fica a seção de script, o que ajudará a unificar o trabalho com os erros recebidos:
<script lang="ts">
import Vue from 'vue'
type Error = {
statusCode: number
message: string
}
type ErrorText = {
title: string
subtitle: string
}
type ErrorTexts = {
[key: number]: ErrorText
default: ErrorText
}
export default Vue.extend({
name: 'ErrorPage',
props: {
error: {
type: Object as () => Error,
required: true,
},
},
data: () => ({
texts: {
404: {
title: '404. Page not found',
subtitle: 'Something went wrong, no such address exists',
},
default: {
title: 'Unknown error',
subtitle: 'Something went wrong, but we`ll try to figure out what`s wrong',
},
} as ErrorTexts,
}),
computed: {
errorText(): ErrorText {
const { statusCode } = this.error
return this.texts[statusCode] || this.texts.default
},
},
})
</script>
O que acontece aqui:
1. Primeiro, definimos os tipos que serão usados neste arquivo.
2. No objeto de dados, criamos um dicionário que conterá mensagens para todos os erros para os quais desejamos exibir uma mensagem única e uma mensagem padrão para todos os outros.
3. Na propriedade calculada errorText, verificamos se o erro recebido está no dicionário. Se houver um erro, retornaremos uma mensagem para ele. Se não houver erro, retorne a mensagem padrão.
Nesse caso, nosso modelo se parecerá com este:
<template lang="pug">
section.section
.content
.ep__container
section-header(
:title="errorText.title"
:subtitle="errorText.subtitle"
)
nuxt-link.ep__link(
class="primary"
to="/"
) Home page
</template>
Observe que aqui estamos usando as classes de utilitário global .section e .content que criamos anteriormente no arquivo assets / styles / global / other.scss. Eles permitem que o conteúdo seja exibido centralizado na página.
Isso usa o componente de cabeçalho de seção, que ainda não foi criado, mas no futuro será um componente universal para exibir cabeçalhos. Vamos implementá-lo quando falarmos sobre componentes.
O diretório de layouts se parece com isto: Vamos começar a criar os componentes.
layouts/
-- default.vue
-- error.vue
Componentes
Os componentes são os blocos de construção de nosso aplicativo. Vamos começar com os componentes que já vimos acima.
Para não inflar o artigo, não descreverei os estilos dos componentes. Eles podem ser encontrados no repositório deste aplicativo.
SectionHeader Os
títulos em nosso aplicativo são feitos no mesmo estilo, portanto, é lógico usar um componente para exibi-los e alterar os dados exibidos por meio dos parâmetros de entrada.
Vamos dar uma olhada na seção de script deste componente:
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'SectionHeader',
props: {
title: {
type: String,
required: true,
},
subtitle: {
type: String,
default: '',
},
},
})
</script>
Agora vamos ver como o modelo ficará:
<template lang="pug">
section.section
.content
h1.sh__title(
class="h1"
) {{ title }}
p.sh__subtitle(
v-if="subtitle"
class="body2 regular"
) {{ subtitle }}
</template>
Como podemos ver, este componente é um invólucro simples para os dados exibidos e não contém nenhuma lógica.
LinkToHome
O componente mais simples em nosso aplicativo é o link acima do título que leva à página inicial da página de postagem selecionada.
Este componente é muito pequeno, então darei todo o seu código de uma vez (sem estilos):
<template lang="pug">
section.section
.content
nuxt-link.lth__link(
to="/"
class="primary"
)
img.lth__link-icon(
src="~/assets/icons/home.svg"
alt="icon-home"
)
| Home
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'LinkToHome',
})
</script>
Observe que estamos solicitando o ícone home.svg do diretório ativos / ícones. Primeiro, você precisa criar este diretório e adicionar o ícone desejado nele.
DbFooter
O componente DbFooter é muito simples. Ele contém direitos autorais e um link para criar uma carta.
Os requisitos são claros, vamos começar a implementação com a seção de script:
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'DbFooter',
computed: {
copyright(): string {
const year = new Date().getUTCFullYear()
return ` ${year} · All rights reserved`
},
},
})
</script>
No DbFooter, temos apenas uma propriedade computada que retorna o ano atual, concatenada com uma determinada string. Agora vamos dar uma olhada no modelo:
<template lang="pug">
section.section
.content
.footer
a.secondary(
href="mailto:example@mail.com?subject=Nuxt blog"
) Contact us
p.footer__copyright(
class="body3 regular"
) {{ copyright }}
</template>
Quando você clicar no link Fale conosco, abriremos o cliente de e-mail nativo e definiremos imediatamente o assunto da mensagem. Esta solução é adequada para uma demonstração de nosso aplicativo, mas na vida real, uma solução mais adequada seria implementar um formulário de feedback para enviar mensagens diretamente do site.
PostCard
O cartão é simples e direta.
<script lang="ts">
import Vue from 'vue'
import { Post } from '~/content/Post'
export default Vue.extend({
name: 'PostCard',
props: {
post: {
type: Object as () => Post,
required: true,
},
},
computed: {
pageUrl(): string {
return `/post/${this.post.id}`
},
},
})
</script>
Na seção de script, definimos um parâmetro de entrada, post, que conterá todas as informações necessárias sobre o post.
Também implementamos a propriedade computada pageUrl para uso no template, que nos retornará um link para a página desejada com o post.
O modelo será semelhante a este:
<template lang="pug">
nuxt-link.pc(:to="pageUrl")
img.pc__img(
:src="getDynamicFile(post.img)"
:alt="`post-image-${post.id}`"
)
p.pc__title(class="body1 medium") {{ post.title }}
p.pc__subtitle(class="body3 regular") {{ post.desc }}
</template>
Observe que o elemento raiz do modelo é nuxt-link. Isso é feito para que o usuário tenha a oportunidade de abrir a postagem em uma nova janela usando o mouse.
Esta é a primeira vez que o mixin getDynamicFile global que criamos anteriormente neste artigo é usado.
PostList
O componente principal na página principal consistirá em um contador de postagens na parte superior e uma lista dos próprios posts.
A seção de script para este componente:
<script lang="ts">
import Vue from 'vue'
import posts from '~/content/posts'
export default Vue.extend({
name: 'PostList',
data: () => ({
posts,
}),
})
</script>
Observe que, após importar o array com postagens, nós os adicionamos ao objeto de dados para que o modelo tenha acesso a esses dados no futuro.
O próprio modelo se parece com isto:
<template lang="pug">
section.section
.content
p.pl__count(class="body2 regular")
img.pl__count-icon(
src="~/assets/icons/list.svg"
alt="icon-list"
)
| Total {{ posts.length }} posts
.pl__items
post-card(
v-for="post in posts"
:key="post.id"
:post="post"
)
</template>
Para que tudo funcione corretamente, não se esqueça de adicionar o ícone list.svg ao diretório assets / icons.
PostFull
PostFull é o componente principal em uma página de postagem separada que será responsável por exibir o texto da postagem.
Para este componente, precisamos do módulo @ nuxtjs / markdownit , que será responsável por converter md em html.
Vamos instalar:
npm i @nuxtjs/markdownit
Em seguida, adicione @ nuxtjs / markdownit à seção de módulos do arquivo nuxt.config.js:
{
modules: [
'@nuxtjs/markdownit',
],
}
Multar! Vamos começar a implementar o componente. Como sempre, na seção de script:
<script lang="ts">
import Vue from 'vue'
import { Post } from '~/content/Post'
export default Vue.extend({
name: 'PostFull',
props: {
post: {
type: Object as () => Post,
required: true,
},
},
})
</script>
Na seção de script, definimos um parâmetro de entrada, post, que conterá todas as informações necessárias sobre o post.
Seguindo para o modelo:
<template lang="pug">
section.section
.content
img.pf__image(
:src="getDynamicFile(post.img)"
:alt="`post-image-${post.id}`"
)
.pf__md(v-html="getDynamicFile(post.file).default")
</template>
Como você pode ver, obtemos e renderizamos dinamicamente uma imagem e um arquivo .md usando nosso mixin getDynamicFile.
Acho que você percebeu que estamos usando o atributo v-html padrão para renderizar o arquivo, uma vez que @ nuxtjs / markdownit fará o resto do trabalho para nós. Incrivelmente simples!
Podemos usar o seletor :: v-deep para acessar a personalização de estilo de nosso arquivo .md renderizado. Dê uma olhada no Github para ver como esse componente é implementado.
Neste componente, eu apenas defini recuos para parágrafos para mostrar o princípio de customização, mas em um aplicativo real, você precisará criar um conjunto completo de estilos para todos os elementos html necessários e usados.
Páginas
Quando todos os componentes estiverem prontos, podemos começar a criar as páginas.
Como você provavelmente já percebeu pelo design, nosso aplicativo consistirá em uma página principal com uma lista de todos os artigos e uma página dinâmica que exibe a postagem selecionada.
A estrutura do diretório de páginas: Todos os componentes são autocontidos e seus estados são determinados por meio de parâmetros de entrada, portanto, nossas páginas parecerão uma lista de componentes especificados na ordem exigida. A página principal será semelhante a esta:
pages/
-- index.vue
-- post/
---- _id.vue
<template lang="pug">
.page
section-header(
title="Nuxt blog"
subtitle="The best blog you can find on the global internet"
)
post-list
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'HomePage',
})
</script>
Para definir o preenchimento correto, usamos a classe global .page que criamos anteriormente em assets / styles / global / other.scss.
Uma única página de postagem parecerá um pouco mais complexa. Vamos dar uma olhada na seção de script primeiro:
<script lang="ts">
import Vue from 'vue'
import { Post } from '~/content/Post'
import posts from '~/content/posts'
export default Vue.extend({
validate({ params }) {
return /^\d+$/.test(params.id)
},
computed: {
currentId(): number {
return Number(this.$route.params.id)
},
currentPost(): Post | undefined {
return posts.find(({ id }) => id === this.currentId)
},
},
})
</script>
Vemos o método de validação. Este método está ausente no Vue, Nuxt fornece para validarmos os parâmetros recebidos do roteador. Validate será chamado sempre que você navegar para uma nova rota. Nesse caso, apenas verificamos se o id passado para nós é um número. Se a validação falhar, o usuário retornará à página de erro error.vue.
Existem 2 propriedades computadas implementadas aqui. Vamos dar uma
olhada mais de perto no que eles fazem: 1. currentId - esta propriedade nos retorna o post id atual (que foi obtido a partir dos parâmetros do roteador), tendo-o previamente convertido para number.
2. currentPost retorna um objeto com informações sobre a postagem selecionada da matriz geral de todas as postagens.
Parece que eles descobriram. Vamos dar uma olhada no modelo:
<template lang="pug">
.page
link-to-home
section-header(
:title="currentPost.title"
)
post-full(
:post="currentPost"
)
</template>
A seção de estilo para esta página, bem como para a página principal, está faltando.
O código das páginas no Github .
Implementar no Hostman
Viva! Nosso aplicativo está quase pronto. É hora de começar a implantá-lo.
Para esta tarefa, usarei a plataforma de nuvem Hostman , que permite automatizar o processo de implantação.
Nosso aplicativo será um site estático, já que um plano gratuito está disponível para sites estáticos no Hostman.
Para publicar, devemos clicar no botão Criar na interface da plataforma, selecionar um plano livre e conectar nosso repositório Github, especificando as opções necessárias para implantação.
Imediatamente depois disso, a publicação começará automaticamente e um domínio livre será criado na zona * .hostman.site com o certificado SSL do Let's Encrypt instalado.
A partir de agora, cada novo push para o branch selecionado (master por padrão) será usado para implantar uma nova versão do aplicativo. Incrivelmente simples e conveniente!
Conclusão
Então, o que temos:
Tentamos mostrar na prática como trabalhar com o framework Nuxt.js. Conseguimos criar um aplicativo simples do início ao fim, desde a criação de um kit de IU até a organização de uma implantação.
Se você seguiu todas as etapas deste artigo, parabéns por criar seu primeiro aplicativo Nuxt.js. Isso foi difícil? Como você trabalha com esta estrutura? Se você tiver alguma dúvida ou solicitação, não hesite em escrever nos comentários.