Diretório de Extensões
O diretório plugins
contém as nossas extensões de JavaScript que queremos executar antes de instanciar a raiz da aplicação de Vue.js.
É nesta pasta onde adicionamos as extensões de Vue e injetamos as funções ou constantes. Toda a vez que precisarmos utilizar Vue.use()
, devemos criar um ficheiro em plugins/
e adicionar o seu caminho na propriedade plugins
no nuxt.config.js
:
Pacotes Externos
Podemos querer utilizar pacotes ou módulos externos na nossa aplicação (um ótimo exemplo é axios
) para fazer requisições de protocolo de hipertexto tanto para o servidor quanto para o cliente.
Primeiro, o instalamos através de npm
ou yarn
:
yarn add @nuxtjs/axios
npm install @nuxtjs/axios
Podemos configurar, por exemplo, os intercetores da axios
para reagir a possíveis erros das suas chamadas de interface de programação de aplicação em toda a aplicação. Neste exemplo, redirecionamos o utilizador para uma página de erro personalizada chamada sorry
quando recebemos um erro de estado 500
da nossa interface de programação de aplicação:
export default function ({ $axios, redirect }) {
$axios.onError(error => {
if (error.response.status === 500) {
redirect('/sorry')
}
})
}
Por último, mas não menos importante, adicionamos o módulo e a extensão recém criada à configuração do projeto:
module.exports = {
modules: ['@nuxtjs/axios'],
plugins: ['~/plugins/axios.js']
}
Depois, podemos utilizá-la diretamente nos componentes da nossa página:
<template>
<h1>{{ post.title }}</h1>
</template>
<script>
export default {
async asyncData ({ $axios, params }) {
const post = await $axios.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
}
}
</script>
Outra maneira de utilizar a axios
sem instalar o módulo é importando a axios
diretamente no marcador <script>
:
<script>
import axios from 'axios'
export default {
async asyncData ({ params }) {
const { data: post } = await axios.get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
}
}
</script>
cannot use import statement outside a module
, podemos precisar adicionar o nosso pacote à opção build
> transpile
no nuxt.config.js
para o carregador da Webpack disponibilizar a nossa extensão.build: {
// Podemos estender a configuração da Webpack neste objeto.
transpile: ['npm-package-name'],
},
Extensões da Vue
Se quisermos usar extensões de Vue, como a v-tooltip
para exibir dicas de ferramentas na nossa aplicação, precisamos configurar a extensão antes de iniciar a aplicação.
Primeiro, precisamos de instalá-la:
yarn add v-tooltip
npm install v-tooltip
Depois criamos o ficheiro plugins/vue-tooltip.js
.
import Vue from 'vue'
import VTooltip from 'v-tooltip'
Vue.use(VTooltip)
A Propriedade plugins
Depois adicionamos o caminho do ficheiro na chave plugins
do nosso nuxt.config.js
. A propriedade plugins
permite-nos adicionar extensões de Vue facilmente à nossa aplicação principal. Todos os caminhos definidos na propriedade plugins
serão importados antes de inicializar a aplicação principal:
export default {
plugins: ['~/plugins/vue-tooltip.js']
}
Extensões de ECMAScript 6
Se a extensão estiver localizada em node_modules
e exportar um módulo de ECMAScript 6, podemos precisar adicioná-la à opção de construção (compilação) transpile
:
module.exports = {
build: {
transpile: ['vue-tooltip']
}
}
Podemos consultar a documentação da configuração da construção (compilação) por mais opções de construção.
Só do Lado do Cliente ou do Servidor
Algumas extensões podem funcionar apenas no navegador porque não têm suporte a interpretação do lado do servidor.
Convenção de Nomeação de Extensão
Se é suposto executar uma extensão apenas no lado do cliente ou do servidor, .client.js
ou .server.js
pode ser aplicado como uma extensão do ficheiro da extensão. O ficheiro será automaticamente incluído apenas no lado respetivo (cliente ou servidor):
export default {
plugins: [
'~/plugins/foo.client.js', // apenas no lado do cliente
'~/plugins/bar.server.js', // apenas no lado do servidor
'~/plugins/baz.js' // ambos cliente e servidor
]
}
Sintaxe de Objeto
Também podemos utilizar a sintaxe de objeto com a propriedade mode
('client'
ou 'server'
) em plugins
:
export default {
plugins: [
{ src: '~/plugins/both-sides.js' },
{ src: '~/plugins/client-only.js', mode: 'client' }, // apenas no lado do cliente
{ src: '~/plugins/server-only.js', mode: 'server' } // apenas no lado do servidor
]
}
Injetar na $root
e no Contexto
Por vezes, queremos disponibilizar funções ou valores em toda a nossa aplicação. Podemos injetar essas variáveis em instâncias de Vue (do lado do cliente), no contexto (do lado do servidor) e até no armazém de estado da Vuex. É uma convenção prefixar essas funções com um $
.
A Nuxt fornece-nos um método inject(key, value)
para fazer isto facilmente. A inject
é dada como segundo parâmetro ao exportar uma função. O $
será anexado automaticamente à chave.
beforeCreate
e created
são chamadas tanto do lado do cliente quanto do lado do servidor. Todas as outras funções gatilhos são chamadas apenas do lado do cliente.export default ({ app }, inject) => {
// Injetar `$hello(msg)` na Vue, contexto e armazém de estado.
inject('hello', msg => console.log(`Hello ${msg}!`))
}
export default {
plugins: ['~/plugins/hello.js']
}
Agora o serviço $hello
pode ser acedido a partir de context
e this
em páginas, componentes, extensões, e ações do armazém de estado:
export default {
mounted() {
this.$hello('mounted')
// imprimirá 'Hello mounted!'
},
asyncData({ app, $hello }) {
$hello('asyncData')
// Se usarmos Nuxt <= 2.12, usamos 👇
app.$hello('asyncData')
}
}
export const state = () => ({
someValue: ''
})
export const actions = {
setSomeValueToWhatever({ commit }) {
this.$hello('store action')
const newValue = 'whatever'
commit('changeSomeValue', newValue)
}
}
Vue.use()
, Vue.component()
, e não é recomendado fazer alterações no protótipo da Vue ou no objeto global da Vue na função exportada pela nossa extensão. (Isto causaria um vazamento de memória no lado do servidor). Consultar também misturas globais .A Propriedade extendPlugins
Podemos querer estender as extensões ou alterar a ordem das extensões criada pela Nuxt. Esta função aceita um vetor de objetos de extensão e deve retornar um vetor de objetos de extensão.
Exemplo de alteração da ordem das extensões:
export default {
extendPlugins(plugins) {
const pluginIndex = plugins.findIndex(
({ src }) => src === '~/plugins/shouldBeFirst.js'
)
const shouldBeFirstPlugin = plugins[pluginIndex]
plugins.splice(pluginIndex, 1)
plugins.unshift(shouldBeFirstPlugin)
return plugins
}
}
Misturas Globais
As misturas globais podem ser facilmente adicionadas com as extensões de Nuxt, mas podem causar problemas e fugas de memória quando não são tratadas corretamente. Sempre que adicionarmos uma mistura global à nossa aplicação, devemos utilizar um sinalizador para evitar registá-la várias vezes:
import Vue from "vue"
// Nos certificamos de que escolhemos um nome único para o sinalizador,
// para não entrar em conflito com qualquer outra mistura.
if (!Vue.__my_mixin__) {
Vue.__my_mixin__ = true
Vue.mixin({ ... }) // Configurar a nossa mistura.
}