1 | <template>
|
2 | <div
|
3 | v-if="prev || next"
|
4 | class="page-nav"
|
5 | >
|
6 | <p class="inner">
|
7 | <span
|
8 | v-if="prev"
|
9 | class="prev"
|
10 | >
|
11 | ←
|
12 | <a
|
13 | v-if="prev.type === 'external'"
|
14 | class="prev"
|
15 | :href="prev.path"
|
16 | target="_blank"
|
17 | rel="noopener noreferrer"
|
18 | >
|
19 | {{ prev.title || prev.path }}
|
20 |
|
21 | <OutboundLink />
|
22 | </a>
|
23 |
|
24 | <RouterLink
|
25 | v-else
|
26 | class="prev"
|
27 | :to="prev.path"
|
28 | >
|
29 | {{ prev.title || prev.path }}
|
30 | </RouterLink>
|
31 | </span>
|
32 |
|
33 | <span
|
34 | v-if="next"
|
35 | class="next"
|
36 | >
|
37 | <a
|
38 | v-if="next.type === 'external'"
|
39 | :href="next.path"
|
40 | target="_blank"
|
41 | rel="noopener noreferrer"
|
42 | >
|
43 | {{ next.title || next.path }}
|
44 |
|
45 | <OutboundLink />
|
46 | </a>
|
47 |
|
48 | <RouterLink
|
49 | v-else
|
50 | :to="next.path"
|
51 | >
|
52 | {{ next.title || next.path }}
|
53 | </RouterLink>
|
54 | →
|
55 | </span>
|
56 | </p>
|
57 | </div>
|
58 | </template>
|
59 |
|
60 | <script>
|
61 | import { resolvePage } from '../util'
|
62 | import isString from 'lodash/isString'
|
63 | import isNil from 'lodash/isNil'
|
64 |
|
65 | export default {
|
66 | name: 'PageNav',
|
67 |
|
68 | props: ['sidebarItems'],
|
69 |
|
70 | computed: {
|
71 | prev () {
|
72 | return resolvePageLink(LINK_TYPES.PREV, this)
|
73 | },
|
74 |
|
75 | next () {
|
76 | return resolvePageLink(LINK_TYPES.NEXT, this)
|
77 | }
|
78 | }
|
79 | }
|
80 |
|
81 | function resolvePrev (page, items) {
|
82 | return find(page, items, -1)
|
83 | }
|
84 |
|
85 | function resolveNext (page, items) {
|
86 | return find(page, items, 1)
|
87 | }
|
88 |
|
89 | const LINK_TYPES = {
|
90 | NEXT: {
|
91 | resolveLink: resolveNext,
|
92 | getThemeLinkConfig: ({ nextLinks }) => nextLinks,
|
93 | getPageLinkConfig: ({ frontmatter }) => frontmatter.next
|
94 | },
|
95 | PREV: {
|
96 | resolveLink: resolvePrev,
|
97 | getThemeLinkConfig: ({ prevLinks }) => prevLinks,
|
98 | getPageLinkConfig: ({ frontmatter }) => frontmatter.prev
|
99 | }
|
100 | }
|
101 |
|
102 | function resolvePageLink (
|
103 | linkType,
|
104 | { $themeConfig, $page, $route, $site, sidebarItems }
|
105 | ) {
|
106 | const { resolveLink, getThemeLinkConfig, getPageLinkConfig } = linkType
|
107 |
|
108 |
|
109 | const themeLinkConfig = getThemeLinkConfig($themeConfig)
|
110 |
|
111 |
|
112 | const pageLinkConfig = getPageLinkConfig($page)
|
113 |
|
114 |
|
115 | const link = isNil(pageLinkConfig) ? themeLinkConfig : pageLinkConfig
|
116 |
|
117 | if (link === false) {
|
118 | return
|
119 | } else if (isString(link)) {
|
120 | return resolvePage($site.pages, link, $route.path)
|
121 | } else {
|
122 | return resolveLink($page, sidebarItems)
|
123 | }
|
124 | }
|
125 |
|
126 | function find (page, items, offset) {
|
127 | const res = []
|
128 | flatten(items, res)
|
129 | for (let i = 0; i < res.length; i++) {
|
130 | const cur = res[i]
|
131 | if (cur.type === 'page' && cur.path === decodeURIComponent(page.path)) {
|
132 | return res[i + offset]
|
133 | }
|
134 | }
|
135 | }
|
136 |
|
137 | function flatten (items, res) {
|
138 | for (let i = 0, l = items.length; i < l; i++) {
|
139 | if (items[i].type === 'group') {
|
140 | flatten(items[i].children || [], res)
|
141 | } else {
|
142 | res.push(items[i])
|
143 | }
|
144 | }
|
145 | }
|
146 | </script>
|
147 |
|
148 | <style lang="stylus">
|
149 | @require '../styles/wrapper.styl'
|
150 |
|
151 | .page-nav
|
152 | @extend $wrapper
|
153 | padding-top 1rem
|
154 | padding-bottom 0
|
155 | .inner
|
156 | min-height 2rem
|
157 | margin-top 0
|
158 | border-top 1px solid $borderColor
|
159 | padding-top 1rem
|
160 | overflow auto // clear float
|
161 | .next
|
162 | float right
|
163 | </style>
|