Русский
Русский
English
Статистика
Реклама

Из песочницы Переключение шаблона страниц во vuejs

Иногда в приложении требуется шаблоны для различных страниц, чтобы не копировать код от компонента к компоненту, мы прописываем шаблон в основном компоненте (он же, обычно, App.vue) и с помощью <router-view> подставляем в него различные вьюшки.


image

Как мы видим, у различных страниц общая шапка. Сайт.

А что, если нам необходимо сделать несколько шаблонов для разных страниц или состояний приложения? Этим мы сейчас и займемся.


Первым делом нам необходимо Vue Js приложение с подключенным роутером.


Что из себя представляют шаблоны? Правильно, обычные компоненты, которые будут вызываться в зависимости от того или иного условия, будь то активная странница, статус аутентификации или (по бреду) время суток.


Подготовим основной компонент для работы с шаблонами.

Если вы создавали проект через 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>...

Теперь создадим пару шаблонов.

Для удобства будем хранить их в отдельной папке layouts.


скриншот структуры папкок

По значимости папка не сильно ушла от components или view, просто удобно.

Есть у Vue такой элемент slot, который позволит нам подставлять наши представления в компонент-шаблон. При отрисовке он заменяется на контент, который мы укажем при вызове компонента. Создадим три шаблона, пусть они будут одинаковыми, с разницей в цвете шапки и подвала, для наглядности.

Синий шаблон, дефолтный:



//ВАШ_ПРОЕКТ/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>

Зеленый шаблон:


//ВАШ_ПРОЕКТ/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>

Красный шаблон:

//ВАШ_ПРОЕКТ/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>

Теперь зарегистрируем эти компоненты-шаблоны в нашем Vue.

//ВАШ_ПРОЕКТ/src/main.jsimport 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 = falsenew Vue({  router,  render: h => h(App)}).$mount('#app')

Отлично! Шаблоны готовы, давайте создадим четыре представления(страницы), два из которых будут отрисовываться с синим шаблоном, а два остальных с красным и зеленым. Они тоже будут одинаковыми, только с разными заголовками.


//ВАШ_ПРОЕКТ/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>

Теперь добавим роуты под наши страницы, и в мета-данных укажем какой шаблон им использовать при отрисовке.


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

Запускаем наше приложение и проверяем:

image

Целиком код можно посмотреть тут
Источник: habr.com
К списку статей
Опубликовано: 04.08.2020 14:20:22
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Vuejs

Разработка веб-сайтов

Vue.js

Javascript

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru