UNPKG

3.19 kBPlain TextView Raw
1<template>
2 <div
3 class="theme-container"
4 :class="pageClasses"
5 @touchstart="onTouchStart"
6 @touchend="onTouchEnd"
7 >
8 <Navbar
9 v-if="shouldShowNavbar"
10 @toggle-sidebar="toggleSidebar"
11 />
12
13 <div
14 class="sidebar-mask"
15 @click="toggleSidebar(false)"
16 />
17
18 <Sidebar
19 :items="sidebarItems"
20 @toggle-sidebar="toggleSidebar"
21 >
22 <template #top>
23 <slot name="sidebar-top" />
24 </template>
25 <template #bottom>
26 <slot name="sidebar-bottom" />
27 </template>
28 </Sidebar>
29
30 <Home v-if="$page.frontmatter.home" />
31
32 <Page
33 v-else
34 :sidebar-items="sidebarItems"
35 >
36 <template #top>
37 <slot name="page-top" />
38 </template>
39 <template #bottom>
40 <slot name="page-bottom" />
41 </template>
42 </Page>
43 </div>
44</template>
45
46<script>
47import Home from '@theme/components/Home.vue'
48import Navbar from '@theme/components/Navbar.vue'
49import Page from '@theme/components/Page.vue'
50import Sidebar from '@theme/components/Sidebar.vue'
51import { resolveSidebarItems } from '../util'
52
53export default {
54 name: 'Layout',
55
56 components: {
57 Home,
58 Page,
59 Sidebar,
60 Navbar
61 },
62
63 data () {
64 return {
65 isSidebarOpen: false
66 }
67 },
68
69 computed: {
70 shouldShowNavbar () {
71 const { themeConfig } = this.$site
72 const { frontmatter } = this.$page
73 if (
74 frontmatter.navbar === false
75 || themeConfig.navbar === false) {
76 return false
77 }
78 return (
79 this.$title
80 || themeConfig.logo
81 || themeConfig.repo
82 || themeConfig.nav
83 || this.$themeLocaleConfig.nav
84 )
85 },
86
87 shouldShowSidebar () {
88 const { frontmatter } = this.$page
89 return (
90 !frontmatter.home
91 && frontmatter.sidebar !== false
92 && this.sidebarItems.length
93 )
94 },
95
96 sidebarItems () {
97 return resolveSidebarItems(
98 this.$page,
99 this.$page.regularPath,
100 this.$site,
101 this.$localePath
102 )
103 },
104
105 pageClasses () {
106 const userPageClass = this.$page.frontmatter.pageClass
107 return [
108 {
109 'no-navbar': !this.shouldShowNavbar,
110 'sidebar-open': this.isSidebarOpen,
111 'no-sidebar': !this.shouldShowSidebar
112 },
113 userPageClass
114 ]
115 }
116 },
117
118 mounted () {
119 this.$router.afterEach(() => {
120 this.isSidebarOpen = false
121 })
122 },
123
124 methods: {
125 toggleSidebar (to) {
126 this.isSidebarOpen = typeof to === 'boolean' ? to : !this.isSidebarOpen
127 this.$emit('toggle-sidebar', this.isSidebarOpen)
128 },
129
130 // side swipe
131 onTouchStart (e) {
132 this.touchStart = {
133 x: e.changedTouches[0].clientX,
134 y: e.changedTouches[0].clientY
135 }
136 },
137
138 onTouchEnd (e) {
139 const dx = e.changedTouches[0].clientX - this.touchStart.x
140 const dy = e.changedTouches[0].clientY - this.touchStart.y
141 if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
142 if (dx > 0 && this.touchStart.x <= 80) {
143 this.toggleSidebar(true)
144 } else {
145 this.toggleSidebar(false)
146 }
147 }
148 }
149 }
150}
151</script>