PageSidebar.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. <template xmlns="http://www.w3.org/1999/html">
  2. <aside class="page-sidebar">
  3. <slot name="top"/>
  4. <div class="page-side-toolbar">
  5. <div class="option-box-toc-fixed" v-if="showPageToc">
  6. <div class="toc-container-sidebar" ref="tocc">
  7. <div class="pos-box">
  8. <div class="icon-arrow"></div>
  9. <div class="scroll-box" style="max-height:650px">
  10. <div style="font-weight:bold;text-align:center;">{{pageSidebarItems[0].title}}</div>
  11. <hr/>
  12. <div class="toc-box">
  13. <PageSidebarToc :depth="0" :items="pageSidebarItems" :sidebarDepth="3"/>
  14. </div>
  15. </div>
  16. </div>
  17. </div>
  18. </div>
  19. <div class="option-box-toc-over" v-on:mouseover="showTocOver($event)" v-on:mouseout="hideTocOver($event)">
  20. <img src="/images/system/toc.png" class="nozoom" />
  21. <span class="show-txt">目录</span>
  22. <div class="toc-container" ref="tocc">
  23. <div class="pos-box">
  24. <div class="icon-arrow"></div>
  25. <div class="scroll-box" style="max-height:550px">
  26. <div style="font-weight:bold;text-align:center;">{{pageSidebarItems[0].title}}</div>
  27. <hr/>
  28. <div class="toc-box">
  29. <PageSidebarToc :depth="0" :items="pageSidebarItems" :sidebarDepth="3"/>
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. <div class="option-box" v-on:mouseover="showToc($event)" v-on:mouseout="hideToc($event)">
  36. <img src="/assets/images/sys/wechat.png" class="nozoom" />
  37. <span class="show-txt">手机看</span>
  38. <div class="toc-container">
  39. <div class="pos-box">
  40. <div class="icon-arrow"></div>
  41. <div class="scroll-box" style="text-align:center" >
  42. <span style="font-size:0.9rem">微信扫一扫</span>
  43. <img v-bind="{src: 'https://api.qrserver.com/v1/create-qr-code/?data=https://offercome.cn'+this.$route.fullPath }" height="180px" style="margin:10px;"/>
  44. 可以<b>手机看</b>或分享至<b>朋友圈</b>
  45. </div>
  46. </div>
  47. </div>
  48. </div>
  49. <!-- <div class="option-box">-->
  50. <!-- <FullScreenBtn />-->
  51. <!-- </div>-->
  52. <div class="option-box" @click="$emit('toggle-sidebar-force')">
  53. <img src="/assets/images/sys/toggle.png" width="30px" class="nozoom" />
  54. <span class="show-txt">左栏</span>
  55. </div>
  56. <div class="option-box" v-on:mouseout="hideToc($event)" v-on:mouseover="showToc($event)" onclick="javascript:window.open('https://wx.zsxq.com/dweb2/index/group/88851482488152','_blank')">
  57. <img class="nozoom" src="/assets/images/sys/xingqiu.png" width="25px" />
  58. <span class="show-txt">星球</span>
  59. <div class="toc-container">
  60. <div class="pos-box">
  61. <div class="icon-arrow"></div>
  62. <div class="scroll-box" style="text-align:center" >
  63. <span style="font-size:0.8rem;font-weight:bold;">一线大厂面试题<span style="font-size:8px;color:red;">「30万字、26门技术栈」</span>、7个技术专栏、「一对一」星球提问、简历指导、送书等</span>
  64. <img height="180px" src="/assets/images/xingqiu/chengxuyuanjinjiequan.jpeg" style="margin:10px;"/>
  65. </div>
  66. </div>
  67. </div>
  68. </div>
  69. <div class="option-box" v-on:mouseover="showToc($event)" v-on:mouseout="hideToc($event)">
  70. <img class="nozoom" src="/images/personal/qrcode.jpg" width="25px" />
  71. <span class="show-txt">读者群</span>
  72. <div class="toc-container">
  73. <div class="pos-box">
  74. <div class="icon-arrow"></div>
  75. <div class="scroll-box" style="text-align:center" >
  76. <span style="font-size:0.8rem;font-weight:bold;">添加Tom哥微信<span style="color:red;">(chixuegao1234)</span>进入学习交流群「抱团取暖」</span>
  77. <img src="/images/personal/qrcode.jpg" height="180px" style="margin:10px;"/>
  78. PS:添加时请备注<b>读者加群</b>,谢谢!
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. <div class="option-box" v-if="prev" style="padding-left:2px;text-align:center;" v-bind:title="prev.title">
  84. <router-link v-if="prev" :to="prev.path" >
  85. <img src="/assets/images/sys/pre2.png" width="30px" class="nozoom" />
  86. <span class="show-txt">上一篇</span>
  87. </router-link>
  88. </div>
  89. <div class="option-box" v-if="next" style="padding-left:2px;text-align:center;" v-bind:title="next.title">
  90. <router-link v-if="next" :to="next.path" >
  91. <img src="/assets/images/sys/next2.png" width="30px" class="nozoom" />
  92. <span class="show-txt">下一篇</span>
  93. </router-link>
  94. </div>
  95. </div>
  96. <slot name="middle"/>
  97. <PageSidebarBackToTop />
  98. <slot name="bottom"/>
  99. </aside>
  100. </template>
  101. <script>
  102. import PageSidebarToc from '@theme/components/PageSidebarToc.vue'
  103. import NavLinks from '@theme/components/NavLinks.vue'
  104. import FullScreenBtn from '@theme/components/FullScreenBtn.vue'
  105. import SiteMap from '@theme/components/SiteMap.vue'
  106. import PageSidebarBackToTop from '@theme/components/PageSidebarBackToTop.vue'
  107. import { resolvePage } from '../util'
  108. export default {
  109. name: 'PageSidebar',
  110. components: { PageSidebarToc, NavLinks, FullScreenBtn, SiteMap, PageSidebarBackToTop },
  111. props: ['pageSidebarItems', 'sidebarItems'],
  112. computed: {
  113. showPageToc () {
  114. return this.prev || this.next
  115. },
  116. prev () {
  117. const prev = this.$page.frontmatter.prev
  118. if (prev === false) {
  119. return
  120. } else if (prev) {
  121. return resolvePage(this.$site.pages, prev, this.$route.path)
  122. } else {
  123. return resolvePrev(this.$page, this.sidebarItems)
  124. }
  125. },
  126. next () {
  127. const next = this.$page.frontmatter.next
  128. if (next === false) {
  129. return
  130. } else if (next) {
  131. return resolvePage(this.$site.pages, next, this.$route.path)
  132. } else {
  133. return resolveNext(this.$page, this.sidebarItems)
  134. }
  135. }
  136. },
  137. methods: {
  138. showToc($event){
  139. $event.currentTarget.className="option-box on";
  140. },
  141. hideToc($event){
  142. $event.currentTarget.className="option-box";
  143. },
  144. showTocOver($event){
  145. $event.currentTarget.className="option-box-toc-over on";
  146. },
  147. hideTocOver($event){
  148. $event.currentTarget.className="option-box-toc-over";
  149. },
  150. showSitemap($event){
  151. $event.currentTarget.className="option-box on";
  152. },
  153. hideSitemap($event){
  154. $event.currentTarget.className="option-box";
  155. }
  156. }
  157. }
  158. function resolvePrev (page, items) {
  159. return find(page, items, -1)
  160. }
  161. function resolveNext (page, items) {
  162. return find(page, items, 1)
  163. }
  164. function find (page, items, offset) {
  165. const res = []
  166. flatten(items, res)
  167. for (let i = 0; i < res.length; i++) {
  168. const cur = res[i]
  169. if (cur.type === 'page' && cur.path === decodeURIComponent(page.path)) {
  170. return res[i + offset]
  171. }
  172. }
  173. }
  174. function flatten (items, res) {
  175. for (let i = 0, l = items.length; i < l; i++) {
  176. if (items[i].type === 'group') {
  177. flatten(items[i].children || [], res)
  178. } else {
  179. res.push(items[i])
  180. }
  181. }
  182. }
  183. </script>
  184. <style lang="stylus">
  185. .page-sidebar
  186. font-size 12px
  187. width 3.8rem
  188. position fixed
  189. z-index 11
  190. margin 0
  191. top 3.6rem
  192. right 0
  193. bottom 0
  194. box-sizing border-box
  195. border-left 0px solid #eaecef
  196. ul
  197. margin 0
  198. a
  199. display inline-block
  200. .nav-links
  201. display none
  202. border-bottom 1px solid $borderColor
  203. padding 0.5rem 0 0.75rem 0
  204. a
  205. font-weight 600
  206. .nav-item, .repo-link
  207. display block
  208. line-height 1.25rem
  209. font-size 1.1em
  210. padding 0.5rem 0 0.5rem 1.5rem
  211. & > .sidebar-links
  212. padding 1.5rem 0
  213. & > li > a.sidebar-link
  214. font-size 1.1em
  215. line-height 1.4
  216. font-weight bold
  217. & > li:not(:first-child)
  218. margin-top .75rem
  219. .toc-container-sidebar
  220. display: block;
  221. position: absolute;
  222. color $textColor
  223. left: 100%;
  224. top: 0px;
  225. margin-left: 16px;
  226. width: 240px;
  227. background: #fff;
  228. left: unset;
  229. right: 100%;
  230. margin-right: 10px;
  231. margin-left: 0;
  232. .on
  233. display: block;
  234. .pos-box
  235. position: relative;
  236. padding: 16px;
  237. .icon-arrow
  238. position: relative;
  239. margin-left: -20px;
  240. .scroll-box
  241. overflow-x: hidden;
  242. overflow-y: hidden;
  243. hr
  244. margin-top: 0.5rem
  245. .toc-box
  246. max-height:600px;
  247. overflow-y: auto;
  248. overflow-x: hidden;
  249. width: 238px;
  250. padding-right: 16px;
  251. -webkit-box-sizing: border-box;
  252. box-sizing: border-box;
  253. & > ol
  254. margin-top: -8px;
  255. li
  256. margin-top: 8px;
  257. line-height: 17px;
  258. text-align: left;
  259. overflow: auto;
  260. text-overflow: ellipsis;
  261. font-size: 12px;
  262. white-space: nowrap;
  263. .sub-box
  264. margin-top: 0;
  265. & > ol > li
  266. padding-left: 15px;
  267. .toc-container
  268. display: none;
  269. position: absolute;
  270. color $textColor
  271. left: 100%;
  272. top: -1px;
  273. margin-left: 16px;
  274. width: 240px;
  275. background: #fff;
  276. border: 1px solid #eee;
  277. // -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
  278. // box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
  279. // border-radius: 4px;
  280. left: unset;
  281. right: 100%;
  282. margin-right: 10px;
  283. margin-left: 0;
  284. .on
  285. display: block;
  286. .pos-box
  287. position: relative;
  288. padding: 16px;
  289. .icon-arrow
  290. position: relative;
  291. margin-left: -20px;
  292. .scroll-box
  293. overflow-x: hidden;
  294. overflow-y: hidden;
  295. hr
  296. margin-top: 0.5rem
  297. .toc-box
  298. max-height: 500px;
  299. overflow-y: auto;
  300. overflow-x: hidden;
  301. width: 238px;
  302. padding-right: 16px;
  303. -webkit-box-sizing: border-box;
  304. box-sizing: border-box;
  305. & > ol
  306. margin-top: -8px;
  307. li
  308. margin-top: 8px;
  309. line-height: 17px;
  310. text-align: left;
  311. overflow: auto;
  312. text-overflow: ellipsis;
  313. font-size: 12px;
  314. white-space: nowrap;
  315. .sub-box
  316. margin-top: 0;
  317. & > ol > li
  318. padding-left: 15px;
  319. .page-side-toolbar
  320. position fixed
  321. right 10px
  322. top 70px !important
  323. width 44px
  324. div.option-box:last-child
  325. border-top 0px solid #eee
  326. div.option-box.on
  327. .toc-container
  328. display block
  329. div.option-box
  330. font-size 12px
  331. position relative
  332. display -webkit-box
  333. display -ms-flexbox
  334. display flex
  335. -webkit-box-orient vertical
  336. -webkit-box-direction normal
  337. -ms-flex-direction column
  338. flex-direction column
  339. -webkit-box-align center
  340. -ms-flex-align center
  341. align-items center
  342. -webkit-box-pack center
  343. -ms-flex-pack center
  344. justify-content center
  345. border-bottom 1px solid #eee
  346. background-color #fff
  347. height 60px
  348. cursor pointer
  349. .img
  350. margin-top 2px
  351. .show-txt
  352. color gray
  353. margin-top 3px
  354. font-size 11px
  355. div.option-box-toc-over
  356. font-size 12px
  357. position relative
  358. display none
  359. -webkit-box-orient vertical
  360. -webkit-box-direction normal
  361. -ms-flex-direction column
  362. flex-direction column
  363. -webkit-box-align center
  364. -ms-flex-align center
  365. align-items center
  366. -webkit-box-pack center
  367. -ms-flex-pack center
  368. justify-content center
  369. border-bottom 1px solid #eee
  370. background-color #fff
  371. height 60px
  372. cursor pointer
  373. .img
  374. margin-top 2px
  375. .show-txt
  376. color gray
  377. margin-top 3px
  378. font-size 11px
  379. .toc-container
  380. margin-right 0
  381. div.option-box-toc
  382. font-size 12px
  383. position relative
  384. display -webkit-box
  385. display -ms-flexbox
  386. display flex
  387. -webkit-box-orient vertical
  388. -webkit-box-direction normal
  389. -ms-flex-direction column
  390. flex-direction column
  391. -webkit-box-align center
  392. -ms-flex-align center
  393. align-items center
  394. -webkit-box-pack center
  395. -ms-flex-pack center
  396. justify-content center
  397. border-bottom 1px solid #eee
  398. background-color #fff
  399. height 60px
  400. cursor pointer
  401. .img
  402. margin-top 2px
  403. .show-txt
  404. color gray
  405. margin-top 3px
  406. font-size 11px
  407. div.option-box:hover
  408. color white
  409. background #eee
  410. div.option-box-toc-over:hover
  411. color white
  412. background #eee
  413. div.option-box-toc-over.on
  414. .toc-container
  415. display block
  416. div.option-box-toc
  417. display none
  418. .page-side-sitemap
  419. position fixed
  420. right 10px
  421. bottom 50px !important
  422. width 44px
  423. div.option-box:last-child
  424. border-bottom 0px solid #eee
  425. div.option-box.on
  426. .sitemap-container
  427. display block
  428. div.option-box
  429. font-size 12px
  430. position relative
  431. display -webkit-box
  432. display -ms-flexbox
  433. display flex
  434. -webkit-box-orient vertical
  435. -webkit-box-direction normal
  436. -ms-flex-direction column
  437. flex-direction column
  438. -webkit-box-align center
  439. -ms-flex-align center
  440. align-items center
  441. -webkit-box-pack center
  442. -ms-flex-pack center
  443. justify-content center
  444. border-bottom 1px solid #eee
  445. background-color #fff
  446. //height 60px
  447. cursor pointer
  448. .show-txt
  449. color gray
  450. margin-top 2px
  451. font-size 11px
  452. padding 4px 0
  453. div.option-box:hover
  454. //color white
  455. //background #eee
  456. .sitemap-container
  457. display: none;
  458. cursor auto
  459. position: absolute;
  460. color $textColor
  461. left: 100%;
  462. bottom: -30px;
  463. height: 500px;
  464. margin-left: 16px;
  465. padding: 0 10px;
  466. width: 850px;
  467. background: #fff;
  468. -webkit-box-shadow: 1px -2px 10px 7px rgba(0,0,0,0.08);
  469. box-shadow: 1px -2px 10px 7px rgba(0,0,0,0.08);
  470. border-radius: 4px;
  471. left: unset;
  472. right: 100%;
  473. margin-right: 2px;
  474. margin-left: 0;
  475. h4
  476. margin: 5px 0;
  477. font-size: 13px;
  478. text-align: center;
  479. padding: 3px 2px;
  480. border-bottom: 1px solid #eaecef;
  481. background: #42b983;
  482. color: white;
  483. .sitemap-top-link
  484. color: white;
  485. font-size: 10px;
  486. float:right;
  487. padding:2px 5px;
  488. text-decoration:underline;
  489. .on
  490. display: block;
  491. .pos-box
  492. position: relative;
  493. padding: 10px;
  494. @media (max-width: $MQNarrow)
  495. .toc-container-sidebar
  496. display none
  497. .option-box-toc
  498. display none
  499. .page-side-toolbar
  500. right 6px
  501. top 65px !important
  502. div.option-box-toc-over
  503. display flex
  504. .page-side-sitemap
  505. right 6px
  506. @media (max-width: $MQMobile)
  507. .toc-container-sidebar
  508. display none
  509. .page-sidebar
  510. display none
  511. .sidebar
  512. .nav-links
  513. display block
  514. .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active::after
  515. top calc(1rem - 2px)
  516. & > .sidebar-links
  517. padding 1rem 0
  518. </style>