# Roteamento e Divisão de Código
# Roteamento com vue-router
Você deve ter notado que nosso código de servidor usa um manipulador *
que aceita URLs arbitrários. Isso nos permite passar a URL visitada para nosso aplicativo Vue e reutilizar a mesma configuração de roteamento para cliente e servidor!
Recomenda-se usar a biblioteca oficial vue-router (opens new window) para esta finalidade. Vamos primeiro criar um arquivo onde criamos o roteador. Observe que, semelhante à instância do aplicativo, também precisamos de uma nova instância do roteador para cada solicitação, portanto, o arquivo exporta uma função createRouter
:
// router.js
import { createRouter } from 'vue-router'
import MyUser from './components/MyUser.vue'
const routes = [{ path: '/user', component: MyUser }]
export default function (history) {
return createRouter({
history,
routes
})
}
2
3
4
5
6
7
8
9
10
11
12
E atualize nossas entradas de cliente e servidor:
// entry-client.js
import { createSSRApp } from 'vue'
import { createWebHistory } from 'vue-router'
import createRouter from './router.js'
import App from './App.vue'
// ...
const app = createSSRApp(App)
const router = createRouter(createWebHistory())
app.use(router)
// ...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// entry-server.js
import { createSSRApp } from 'vue'
// o roteador do servidor usa um histórico diferente do cliente
import { createMemoryHistory } from 'vue-router'
import createRouter from './router.js'
import App from './App.vue'
export default function () {
const app = createSSRApp(App)
const router = createRouter(createMemoryHistory())
app.use(router)
return {
app,
router
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Divisão de Código
Dividir código, ou carregar preguiçosamente parte do seu aplicativo, ajuda a reduzir o tamanho dos assets que precisam ser baixados pelo navegador para a renderização inicial e pode melhorar muito o TTI (tempo até a interatividade) para aplicativos com grandes pacotes. A chave é "carregar apenas o que é necessário" para a tela inicial.
O Vue Router fornece suporte a carregamento preguiçoso (opens new window), permitindo o webpack dividir o código naquele ponto (opens new window). Tudo que você precisa fazer é:
// mude isso...
import MyUser from './components/MyUser.vue'
const routes = [{ path: '/user', component: MyUser }]
// para isso:
const routes = [
{ path: '/user', component: () => import('./components/MyUser.vue') }
]
2
3
4
5
6
7
8
Tanto no cliente quanto no servidor, precisamos esperar que o roteador resolva os componentes de rota assíncrona antecipadamente para invocar corretamente os gatilhos no componente. Para isso, usaremos o método router.isReady (opens new window). Vamos atualizar nossa entrada de cliente:
// entry-client.js
import { createSSRApp } from 'vue'
import { createWebHistory } from 'vue-router'
import createRouter from './router.js'
import App from './App.vue'
const app = createSSRApp(App)
const router = createRouter(createWebHistory())
app.use(router)
router.isReady().then(() => {
app.mount('#app')
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Também precisamos atualizar nosso script server.js
:
// server.js
const path = require('path')
const appPath = path.join(__dirname, './dist', 'server', manifest['app.js'])
const createApp = require(appPath).default
server.get('*', async (req, res) => {
const { app, router } = createApp()
await router.push(req.url)
await router.isReady()
const appContent = await renderToString(app)
fs.readFile(path.join(__dirname, '/dist/client/index.html'), (err, html) => {
if (err) {
throw err
}
html = html
.toString()
.replace('<div id="app">', `<div id="app">${appContent}`)
res.setHeader('Content-Type', 'text/html')
res.send(html)
})
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26