Учебник по навигационным ящикам с Nuxt
Придумать навигацию, которая хорошо выглядит и отзывчива на небольших устройствах, может быть непросто. Это позволит вам начать работу с адаптивной навигацией без необходимости раздувания проекта сторонним плагином.
Отзывчивость была достигнута с помощью сетки CSS. Если вам еще предстоит погрузиться в этот мощный и в то же время элегантный способ достижения отзывчивости, загляните сюда.
В этом руководстве предполагается, что вы уже знакомы с Nuxt (фреймворк для написания универсального приложения на Vue), его структурой папок и Vuex (библиотекой управления состоянием для Vue).
Требования.
буду пользоваться имеющимся nuxt-create-app
инструмент для быстрого создания этого приложения. Не стесняйтесь создавать приложение Nuxt с нуля.
Итак, используя nuxt-create-app
тебе нужно иметь npx
установлен на вашем устройстве. npx поставляется с NPM
начиная с версии 5.2.0.
Однако вам потребуется установить NPM и Node либо для запуска проекта с нуля, либо для использования nuxt-create-app
инструмент.
Следуйте этим простым шагам, чтобы установить Nuxt. Мы собираемся сохранить варианты очень простыми.
- Бежать
npx create-nuxt-app <project-name>
(в данном случае navigation-nav — это название нашего проекта. Вы можете изменить его на любое другое). - Выбирать
none
для серверных фреймворков, фреймворка пользовательского интерфейса, фреймворка тестирования. - Выбирать
spa
Режим - Выберите ничего для
axios
а такжеlinters
- Перейдите к проекту и запустите
npm install
- Наконец, npm run dev. Если все пойдет хорошо, вы увидите, что ваше приложение работает на локальном хосте: 3000.
Макет по умолчанию
Здесь будут размещены компоненты, общие для всех страниц. Этот файл будет иметь TheHeader
, TheSideNav
, TheFooter
а по умолчанию nuxt
составная часть.
<template>
<div class="app-container">
<TheHeader/>
<TheSideNav/>
<div class="app-content">
<nuxt />
</div>
<TheFooter/>
</div>
</template>
<script>
import TheHeader from '~/components/TheHeader'
import TheFooter from '~/components/TheFooter'
import TheSideNav from '~/components/TheSideNav'
export default {
components: {
TheHeader,
TheSideNav,
TheFooter
},
computed: {
isSidebar() {
return this.$store.getters['nav/toggleSidebar']
}
},
watch: {
'$route': function() {
if (process.client && this.isSidebar && window.innerWidth < 768) {
this.$store.dispatch('nav/toggleSidebar')
}
}
}
</script>
<style>
html, body{
margin: 0;
height: 100%;
width: 100%;
}
.app-container{
height: 100%;
position: relative;
display: grid;
grid-template: auto 1fr auto / 1fr;
}
.app-content{
min-height: 100vh;
padding: 24px;
display: grid;
align-items: center;
justify-items: center;
}
</style>
Ссылки на приложения
Поскольку ссылки будут одинаковыми в TheHeader
а также TheSideNav
компоненты, я создам файл в каталоге компонентов и назову его appLinks.vue
поэтому его можно использовать повторно.
<template>
<ul class="nav-list">
<li class="nav-item"><nuxt-link to="/about">About</nuxt-link></li>
<li class="nav-item"><nuxt-link to="/services">Services</nuxt-link></li>
<li class="nav-item"><nuxt-link to="/contact">Contact</nuxt-link></li>
</ul>
</template>
<style scoped>
.nav-list {
list-style: none;
padding: 0;
margin: 0;
}
.nav-item {
margin: 0 10px;
}
.nav-item a {
text-decoration: none;
color: #fefefe;
}
.nav-item a:hover,
.nav-item a:active{
color: #b4b4b4;
}
@media (max-width: 767px) {
.nav-list {
display: block;
}
.nav-item{
margin-top: 16px;
margin-bottom: 16px;
}
}
@media (min-width: 768px) {
.nav-list {
display: flex;
}
}
</style>
Заголовок
Этот файл будет иметь название бренда, кнопку-переключатель, которая отображается на меньшем устройстве, и, конечно же, ссылки на приложения, которые мы изначально создали.
Суть этого урока заключается в этом компоненте и, в частности, в кнопке-переключателе.
Элемент переключения имеет v-on:click
прилагаемая к нему директива (я предпочитаю краткую форму, @click
). Когда этот элемент щелкнут, он отправляет theToggleSidebar
действие в навигационном модуле. Состояние toggleSibebar определяет, будет ли отображаться боковая панель или нет. Этот же код работает рука об руку с элементом фона внутри. theTheSideNav
составная часть.
<template>
<header>
<div class="brand-name">
<nuxt-link to="/">HAPPY VUE YEAR</nuxt-link>
</div>
<div class="drawer-toggle" role="button" @click="$store.dispatch('nav/toggleSidebar')">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
<div class="app-links">
<app-links></app-links>
</div>
</header>
</template>
<script>
import AppLinks from '~/components/appLinks'
export default {
components: { AppLinks }
}
</script>
<style scoped>
header{
display: grid;
grid-template: 60px / auto 1fr;
align-items: center;
background-color: #333;
}
.app-links{
justify-self: end;
}
.brand-name {
margin: 0 10px;
font-size: 1.3rem;
}
.brand-name a {
text-decoration: none;
color: white;
}
.drawer-toggle .bar {
width: 90%;
height: 2px;
background-color: white;
}
.drawer-toggle {
display: flex;
justify-self: end;
flex-direction: column;
justify-content: space-around;
height: 50%;
width: 35px;
padding-right: 16px;
cursor: pointer;
}
@media (max-width: 767px) {
header{
padding: 0 16px;
}
header:nth-child{
justify-self: end !important;
}
.app-links {
display: none;
}
}
@media (min-width: 768px) {
header{
padding: 0 64px;
}
.app-links {
display: block;
}
.drawer-toggle {
display: none;
}
}
</style>
Боковая панель навигации
Этот элемент имеет toggleSidebar
метод в computed
собственность TheSideNav
составная часть. Значение логическое. У этого элемента также есть фон, как было сказано ранее. При нажатии кнопки переключения или фонового изображения toggleSibebar
состояние в навигационном модуле (хранилище) изменяется либо на true
или же false
. Следовательно, это изменение получено в computed
собственность через toggleSidebar
созданный нами метод.
Я добавил эффект перехода на боковую панель, чтобы было удобнее переключать боковую панель. Это было сделано без особых усилий благодаря компоненту оболочки перехода Vue.
<template>
<div class="sidenav-container">
<div v-if="toggleSidebar" class="backdrop" @click="$store.dispatch('nav/toggleSidebar')"></div>
<transition name="slide-side">
<div v-if="toggleSidebar" class="sidenav">
<app-links></app-links>
</div>
</transition>
</div>
</template>
<script>
import AppLinks from '~/components/appLinks'
export default {
components: { AppLinks },
computed: {
toggleSidebar() {
return this.$store.getters['nav/toggleSidebar']
}
}
}
</script>
<style scoped>
.sidenav-container {
height: 100%;
width: 100%;
}
.sidenav {
height: 100%;
width: 300px;
background-color: #d6d6d6;
z-index: 10000;
position: fixed;
top: 0;
left: 0;
box-sizing: border-box;
padding: 30px;
}
.backdrop {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 1000;
position: fixed;
top: 0;
left: 0;
}
.slide-side-enter-active,
.slide-side-leave-active {
transition: all 0.3s ease-out;
}
.slide-side-enter,
.slide-side-leave-to {
transform: translateX(-100%);
}
</style>
Магазин
Я выбрал модульный метод. Классический способ управления состоянием будет объявлен устаревшим в следующем выпуске Nuxt. Наш nav
модуль довольно простой. Он имеет нормальные обработчики state
, mutations
, actions
а также getters
.
// States
export const state = () =>({
toggleSidebar: false
})
// mutations
export const mutations = {
TOGGLE_SIDEBAR(state) {
state.toggleSidebar = !state.toggleSidebar
}
}
// actions
export const actions = {
toggleSidebar({ commit }) {
commit('TOGGLE_SIDEBAR')
}
}
// Getters
export const getters = {
toggleSidebar: state => state.toggleSidebar,
}
Мобильный вид!.
Вывод
Нам удалось создать классный навигационный ящик, который хорошо работает на небольших устройствах, используя простую сетку CSS и Vuex в приложении Nuxt.
Полный код можно найти на Гитхаб и демо-версия здесь
Этот пост был впервые опубликован здесь.