A veces, una aplicación requiere plantillas para diferentes páginas, para no copiar el código de un componente a otro, escribimos la plantilla en el componente principal (también conocido como App.vue, por lo general) y usamos <router-view> para sustituir varias vistas en él.
Como podemos ver, diferentes páginas tienen un encabezado común. Sitio web.
¿Qué pasa si necesitamos crear varias plantillas para diferentes páginas o estados de aplicación? Esto es lo que haremos ahora.
En primer lugar, necesitamos una aplicación Vue Js con un enrutador conectado.
? , , , , ( ) .
.
Vue-Cli :
//_/src/App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
(Computed) «script» ( , vue ).
- , — .
//_/src/App.vue
...
<script>
export default {
computed: {
//
layout(){
//
//( , )
return this.$route.meta.layout || "default-layout"
}
}
}
</script>
...
«template» — , layout.
//_/src/App.vue
<template>
<div id="app">
<!-- -->
<component :is="layout">
<router-view/>
</component>
</div>
</template>
...
Ahora creemos un par de plantillas.
Para mayor comodidad, los almacenaremos en una carpeta de "diseños" separada.
En términos de importancia, la carpeta no se ha alejado mucho de los componentes o la vista, simplemente es conveniente.
Vue tiene un elemento de ranura que nos permitirá inyectar nuestras vistas en un componente de plantilla. Cuando se procesa, se reemplaza con el contenido que especificaremos al llamar al componente. Creemos tres plantillas, que sean iguales, con una diferencia en el color del encabezado y pie de página, para mayor claridad.
Plantilla azul, predeterminada:
//_/src/layouts/Default.vue
<template>
<div>
<header>
<ul class="nav">
<li><router-link class="link" to="/"> </router-link></li>
<li><router-link class="link" to="/page2"> 1</router-link></li>
<li><router-link class="link" to="/page3"> 2</router-link></li>
<li><router-link class="link" to="/page4"> 2</router-link></li>
</ul>
</header>
<section class="content">
<!--, view-->
<slot/>
</section>
<footer>
</footer>
</div>
</template>
<script>
export default {
name: "Default"
}
</script>
<style scoped>
header{
background-color: blue;
height: 70px;
display: flex;
align-items: center;
}
footer{
background-color: blue;
height: 70px;
}
.content{
min-height: calc(100vh - 140px);
}
ul{
list-style: none;
margin: 0;
color: white;
}
li{
color: white;
display: inline;
margin: 0 5px;
}
.link{
color: white;
text-decoration: none;
}
</style>
Patrón verde:
//_/src/layouts/Green.vue
<template>
<div>
<header>
<ul class="nav">
<li><router-link class="link" to="/"> </router-link></li>
<li><router-link class="link" to="/page2"> 1</router-link></li>
<li><router-link class="link" to="/page3"> 2</router-link></li>
<li><router-link class="link" to="/page4"> 2</router-link></li>
</ul>
</header>
<section class="content">
<!--, view-->
<slot/>
</section>
<footer>
</footer>
</div>
</template>
<script>
export default {
name: "green"
}
</script>
<style scoped>
header{
background-color: green;
height: 70px;
display: flex;
align-items: center;
}
footer{
background-color: green;
height: 70px;
}
.content{
min-height: calc(100vh - 140px);
}
ul{
list-style: none;
margin: 0;
color: white;
}
li{
color: white;
display: inline;
margin: 0 5px;
}
.link{
color: white;
text-decoration: none;
}
</style>
Patrón rojo:
//_/src/layouts/Red.vue
<template>
<div>
<header>
<ul class="nav">
<li><router-link class="link" to="/"> </router-link></li>
<li><router-link class="link" to="/page2"> 1</router-link></li>
<li><router-link class="link" to="/page3"> 2</router-link></li>
<li><router-link class="link" to="/page4"> 2</router-link></li>
</ul>
</header>
<section class="content">
<!--, view-->
<slot/>
</section>
<footer>
</footer>
</div>
</template>
<script>
export default {
name: "Red"
}
</script>
<style scoped>
header{
background-color: red;
height: 70px;
display: flex;
align-items: center;
}
footer{
background-color: red;
height: 70px;
}
.content{
min-height: calc(100vh - 140px);
}
ul{
list-style: none;
margin: 0;
color: white;
}
li{
color: white;
display: inline;
margin: 0 5px;
}
.link{
color: white;
text-decoration: none;
}
</style>
Ahora registremos estos componentes de plantilla en nuestro Vue.
//_/src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//
import DefaultLayout from "./layouts/Default"
import GreenLayout from "./layouts/Green"
import RedLayout from "./layouts/Red"
//
Vue.component("default-layout", DefaultLayout)
Vue.component("green-layout", GreenLayout)
Vue.component("red-layout", RedLayout)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
¡Excelente! Las plantillas están listas, creemos cuatro vistas (páginas), dos de las cuales se renderizarán con una plantilla azul y las otras dos con una roja y una verde. También serán iguales, solo que con diferentes títulos.
//_/src/views/page1.vue
<template>
<div>
<h1> </h1>
</div>
</template>
<script>
export default {
name: "Page1"
}
</script>
<style scoped>
</style>
//_/src/views/page2.vue
<template>
<div>
<h1> </h1>
</div>
</template>
<script>
export default {
name: "Page2"
}
</script>
<style scoped>
</style>
//_/src/views/page3.vue
<template>
<div>
<h1> </h1>
</div>
</template>
<script>
export default {
name: "Page3"
}
</script>
<style scoped>
</style>
//_/src/views/page4.vue
<template>
<div>
<h1> </h1>
</div>
</template>
<script>
export default {
name: "Page4"
}
</script>
<style scoped>
</style>
Ahora agregaremos rutas para nuestras páginas, y en los metadatos indicaremos qué plantilla usar al renderizar.
import Vue from 'vue'
import VueRouter from 'vue-router'
//
import Page1 from "../views/Page1"
import Page2 from "../views/Page2"
import Page3 from "../views/Page3"
import Page4 from "../views/Page4"
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Page1
//, , -
},
{
path: '/page2',
name: 'Page2',
component: Page2,
// -,
//
meta:{
layout: "green-layout"
}
},
{
path: '/page3',
name: 'Page3',
component: Page3,
meta:{
layout: "red-layout"
}
},
{
path: '/page4',
name: 'Page4',
component: Page4,
// ,
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
Lanzamos nuestra aplicación y comprobamos: El
código completo se puede ver aquí