VuePress搭建我的技術文檔網站教程

VuePress 由兩部分組成:一部分是支持用 Vue 開發主題的極簡靜態網站生成器,另外一個部分是爲書寫技術文檔而優化的默認主題。它的誕生初衷是爲了支持 Vue 及其子項目的文檔需求。javascript

每個由 VuePress 生成的頁面都帶有預渲染好的 HTML,也所以具備很是好的加載性能和搜索引擎優化(SEO)。同時,一旦頁面被加載,Vue 將接管這些靜態內容,並將其轉換成一個完整的單頁應用(SPA),其餘的頁面則會只在用戶瀏覽到的時候才按需加載。html

1. 安裝

1.1 依賴環境:node8.0以上的版本

若是沒有安裝node,可在node官網選擇對應操做系統下載安裝:https://nodejs.org/zh-cn/
可在終端使用node -v命令來查看node版本,如:v8.12.0
若是你的node版本低,請把node版本升級到8.0以上。
如何升級node:https://segmentfault.com/a/11...vue

1.2 安裝VuePress

全局安裝,打開終端,輸入以下命令:java

~ npm install -g vuepress

http fetch GET 200 https://registry.npm.taobao.org/caniuse-db/download/caniuse-db-1.0.30000909.tgz 3993ms
/usr/local/bin/vuepress -> /usr/local/lib/node_modules/vuepress/bin/vuepress.js
+ vuepress@0.14.5
removed 1 package and updated 13 packages in 68.944s

圖片描述
安裝結束後,可在終端使用vuepress --version來查看vuepress版本node

2. 啓動一個服務

首先在終端建立一個文件夾,做爲項目目錄,而後建立一個md文件:webpack

~ mkdir press
~ cd press
# 新建一個 markdown 文件
~ echo '# Hello VuePress!' > README.md

而後終端輸入以下命令來啓動vuepress服務:git

~ vuepress dev .


 WAIT  Extracting site metadata...

 DONE  [00:34:16] Build 94707d finished in 5175 ms!

> VuePress dev server listening at http://localhost:8080/

clipboard.png

此時在瀏覽器中輸入http://localhost:8080/就能瀏覽效果了。github

圖片描述

3. 配置文件說明

配置須要在文檔目錄下建立一個.vuepress目錄,全部 VuePress 相關的文件都將會被放在這裏。
終端建立一個文件夾:web

mkdir .vuepress

其中有一個最重要的文件.vuepress/config.js,網站的全部文件的配置都在這個文件裏面,
須要建立該文件touch .vuepress/config.js,該文件要導出一個JavaScript 對象:算法

module.exports = {
  title: '我的文檔',
  description: '練習文檔'
}

如今的目錄結構:

.
├── .vuepress
│   └── config.js
└── README.md

4. 關於每一個頁面和路徑說明

在vuepress裏面,一個md文件就是一個頁面,如在下面的目錄結構中:

./
├── .vuepress
│   └── config.js
├── README.md
├── home1.md
└── page-a
    ├── README.md
    ├── a.md
    ├── b.md
    └── 你好.md

因爲服務是在./啓動的,因此路徑以./爲服務根路徑。

  • 默認主頁
    服務啓動後,默認找到的是./README.md文件,也就是http://localhost:8080/
  • ./home1.md
    該文件在服務中的路徑http://localhost:8080/home1.html
    在vuepress中配置路徑/home1
  • ./page-a/README.md
    該文件在服務路徑:http://localhost:8080/page-a/時默認找的文件。
    注意URL最後的/不能少,不然會去找./page-a.md文件。
  • ./page-a/a.md
    該文件在服務的路徑:http://localhost:8080/page-a/a.html

注: md文件的文件名能夠是中文,可是文件夾名字必定要是英文的。

5. 首頁設置

vuepress內置了一個主頁樣式,是Front-matter格式的,
Front-matter教程:https://hexo.io/zh-cn/docs/fr...
首頁的文件是根級README.md文件,在文件中寫入以下配置:

---
home: true
heroImage: 
actionText: 快速上手 →
actionLink: /zh/guide/
features:
- title: 簡潔至上
  details: 以 Markdown 爲中心的項目結構,以最少的配置幫助你專一於寫做。
- title: Vue驅動
  details: 享受 Vue + webpack 的開發體驗,在 Markdown 中使用 Vue 組件,同時可使用 Vue 來開發自定義主題。
- title: 高性能
  details: VuePress 爲每一個頁面預渲染生成靜態的 HTML,同時在頁面被加載的時候,將做爲 SPA 運行。
footer: MIT Licensed | Copyright © 2018-present Evan You
---
# Hello VuePress!

保存文件後頁面效果以下圖所示:
圖片描述
注意Front-matter必定要在md文件的頂部,不然不會生效。

6. 導航欄配置

導航欄可能包含你的頁面標題、搜索框、 導航欄連接、多語言切換、倉庫連接,它們均取決於你的配置。
導航欄經過.vuepress/config.js文件的themeConfig.nav來配置:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    nav: [
      { text: 'Home', link: '/' },                      // 根路徑
      { text: 'Guide', link: '/guide/' },
      { text: 'External', link: 'https://google.com' }, // 外部連接
      // 顯示下拉列表
      {
        text: 'Languages',
        items: [
          { text: 'Chinese', link: '/language/chinese' },
          { text: 'Japanese', link: '/language/japanese' }
        ]
      },
      // 下拉列表顯示分組
      {
        text: '高級',
        items: [
          { 
            text: '算法', 
            items: [
              { text: '冒泡', link: '/language/chinese' },
              { text: '快速', link: '/language/japanese' }
            ] 
          },
          { 
            text: '設計模式', 
            items: [
              { text: '工廠', link: '/language/chinese' },
              { text: '單例', link: '/language/chinese'},
            ] 
          },
        ]
      }
    ]
  }
}

文件保存後,頁面導航效果:
clipboard.png

vuepress官方文檔中關於導航欄的介紹:https://v0.vuepress.vuejs.org...

7. 側邊欄設置

若是你什麼也不作,那麼一個頁面是沒有側邊欄的,以下圖所示:

clipboard.png

若是想要配置側邊欄,須要用到sidebar參數,該參數能夠在配置文件中配置,也能夠在每一個md文件中配置。

7.1 自動生成側邊欄(僅當前頁面)

兩種方法:

  1. 在md文件的頂部寫上下面代碼:

    ---
    sidebar: auto
    ---

    此配置之針對當前md文件生效。
    注:此格式是YAML front matter,必定要在md文件的頂部纔會生效。

  2. .vuepress/config.js中配置

    // .vuepress/config.js
    module.exports = {
      themeConfig: {
        sidebar: 'auto'
      }
    }

    在配置文件中設置這句話後,全部頁面都會生效。

配置後頁面效果:

clipboard.png

7.2 設置側邊欄標題顯示的層數

默認狀況下,側邊欄會自動顯示當前頁面的標題(h2~h3)組成的連接,按照頁面自己的結構進行嵌套。
側邊欄不會顯示h1標題,從h2開始顯示,最多顯示到h3
能夠經過在配置文件中配置themeConfig.sidebarDepth來設置嵌套層級

// .vuepress/config.js
 module.exports = {
   themeConfig: {
     sidebarDepth: 2,
   }
 }

或者在md文件的頂部使用YAML front matter來爲某個頁面重寫此值:

---
sidebarDepth: 2
---

sidebarDepth可設置的值:

說明
0 禁用標題(headers)連接
1 默認值,只顯示h2的標題
2 可設置的最大值,再大無效, 同時提取h2h3標題

注:若是設置了 sidebar: 'auto' ,側邊欄會顯示h2h3標題,此時sidebarDepth的值只有0是生效的(僅顯示h2的標題),這裏須要注意一下。

在md文件中標題的寫法:

# 這是一級標題,對應HTML中<h1>標籤

## 這是二級標題,對應HTML中<h2>標籤

### 這是三級標題,對應HTML中<h3>標籤
....

7.3 項目只顯示一個側邊欄

若是想要全部頁面顯示一個側邊欄,那麼須要在配置文件中添加sidebar字段:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/home1',
      ['/home2', 'home2自定義標題'],
      '/home3',
      '中文',
    ]
  }
}

說明:

  1. 能夠省略 .md 拓展名
  2. /結尾的路徑將會被視爲*/README.md
  3. 頁面的連接文字自動獲取(頁面的第一個header),若是明確地在 YAML front matter 中指定頁面的標題,則
    顯示front matter中的標題。
  4. 也能夠指定連接的文字,使用一個格式爲 [link, text] 的數組。

md文件頂部使用front matter設置標題的方法:

---
title: 自定義標題
---

配置好後頁面效果:

clipboard.png

7.4 側邊欄分組

你能夠經過使用對象來將側邊欄劃分紅多個組

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      {
        title: '一組題目',
        collapsable: false,
        children: [
          '/', '/home1',
        ]
      },
      {
        title: '二組題目',
        children: [
          ['/home2', 'home2自定義題目'], 
          '/home3',
          '/中文',
        ]
      }
    ]
  }
}

側邊欄的每一個子組默認是可摺疊的,你能夠設置 collapsable: false 來讓一個組永遠都是展開狀態。

設置後頁面效果,其中二組題目是能夠摺疊的:
clipboard.png

7.5 設置多個側邊欄

若是你想爲不一樣的頁面組來顯示不一樣的側邊欄,須要把一個側邊欄下的多個文件放在一個目錄下,一個側邊欄一個目錄,以下面的文件結構:

.
├── README.md
├── home1.md
├── home2.md
├── home3.md
├── bar
│   ├── README.md
│   ├── one.md
│   └── two.md
└── page-a
    ├── README.md
    ├── a.md
    └── b.md

配置文件中的sidebar作以下設置:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: {
      // /bar/ 一個側邊欄,裏面的三個頁面共用一個側邊欄
      '/bar/': [
        '',           // ./bar/README.md文件,對應頁面上/bar/路徑
        'one',        // ./bar/one.md文件,對應頁面上/bar/one.html
        'two',        // ./bar/two.md文件,對應頁面上/bar/two.html
      ],
      '/page-a/': [
        '',
        'a',
        'b',
      ],
      // 確保'/'側邊欄被最後定義。VuePress 會按順序遍歷側邊欄配置來尋找匹配的配置。
      '/': [
        '',
        'home1',
        'home2',
        'home3',
      ],
    },
  }
}

7.6 關於側邊欄每一個頁面顯示的標題

側邊欄每一個頁面的標題可從以下三個地方獲取,三種方式選一個配置就能夠了。
一、 YAML front matter 中指定頁面的標題:

---
title: 自定義標題
---

二、在配置文件中配置的路徑,如:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      ['/page-b', '自定義的標題']
    ]
  }
}

三、若是上面方法沒有設置,那麼頁面將會取頁面中第一個header做爲標題。

8. vuepress/config.js中其餘配置

8.1 設置路徑別名,解決引入圖片路徑問題

若是想要在md文件中引入圖片,一種是使用圖片的相對地址,這種方式有的時候路徑會很長,並且文件移動到另一個文件夾後,還須要修改圖片的引用路徑。
若是你有這個煩惱,那麼能夠經過給圖片路徑配置別名的方式來直接使用別名代替路徑,使用方式以下:

// .vuepress/config.js
const path = require('path');

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        '@vuepress': path.join(__dirname, '../images/vuepress'),
      }
    }
  }
}

上面../images/vuepress路徑是相對於config.js文件的路徑。
而後就能夠在MD文件中使用以下方式引入圖片了:

![](~@vuepress/003.png)

8.2 設置搜索使用Algolia搜索

內置搜索只會爲頁面的標題、h2 和 h3 構建搜索索引,若是你須要全文搜索,你可使用 Algolia 搜索。
algolia網站來註冊而後本身上傳網站很是麻煩。
algolia提供了簡化的方式Algolia DocSearch ,只須要提交本身的網站,而後加入少許的腳本,就能使用了。
具體使用方法:
一、打開Algolia DocSearch,大約在最下面,輸入本身的文檔地址和郵箱。

clipboard.png

二、Algolia DocSearch會發送確認郵件,收到後須要回覆一下這個網站是你本身的,而且能夠修改網站代碼:

clipboard.png

三、Algolia DocSearch會發送一封使用郵件,裏面有apiKeyindexName

clipboard.png

四、在配置文件中添加以下內容, apiKey和indexName就是上面郵件中的內容:

module.exports = {
  themeConfig: {
    algolia: {
      apiKey: '<API_KEY>',
      indexName: '<INDEX_NAME>'
    }
  }
}

最終頁面效果:

clipboard.png

9. 項目部署

目前服務啓動的只是本地服務,vuepress還能夠把文檔生成靜態html文件項目,部署到服務器或第三方託管網站上。
生成最終靜態文件命令:

vuepress build .

該命令執行完畢後會在.vuepress文件夾下生成dist目錄:

該目錄裏面的文件就是生成的最終靜態HTML文件,可把該目錄複製到服務器或第三方託管網站部署成本身的文檔網站。

9.1 部署到GitHub Pages

若是你打算髮布到https://<USERNAME>.github.io/,則能夠省略這一步,由於 base 默認便是 "/"

若是你打算髮布到https://<USERNAME>.github.io/<REPO>/(也就是說你的倉庫在 https://github.com/<USERNAME>/<REPO>),則將base設置爲"/<REPO>/"

設置base的值:

// .vuepress/config.js
module.exports = {
  base: '/press/',     // 倉庫名字是press
  themeConfig: {}
}

9.1.2 建立一個自動執行腳本

爲了方便部署,可建立一個自動部署腳本文件deploy.sh,文件內容以下:

#!/usr/bin/env sh

echo '開始執行命令'
# 生成靜態文件
echo '執行命令:vuepress build .'
vuepress build .

# 進入生成的文件夾
echo "執行命令:cd ./.vuepress/dist\n"
cd ./.vuepress/dist

# 初始化一個倉庫,僅僅是作了一個初始化的操做,項目裏的文件尚未被跟蹤
echo "執行命令:git init\n"
git init

# 保存全部的修改
echo "執行命令:git add -A"
git add -A

# 把修改的文件提交
echo "執行命令:commit -m 'deploy'"
git commit -m 'deploy'

# 若是發佈到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master

# 若是發佈到 https://<USERNAME>.github.io/<REPO>
# git push -f https://github.com/<USERNAME>/<REPO>.git master:gh-pages

# 返回到上一次的工做目錄
echo "回到剛纔工做目錄"
cd -

而後在終端執行以下命令來運行腳本:

bash deploy.sh

還可使用./deploy.sh命令,不過該命令須要deploy.sh文件是可執行文件,在終端輸入以下命令可把文件變成可執行文件:

chmod +x deploy.sh

注意:

  1. vuepress每次執行後都會先刪除dist目錄,而後重新打包的,全部git都是重新添加在提交。
  2. git推送是強制push的,因此github上倉庫只會有一次提交。
  3. 推薦把打包後的文件傳到gh-pages分支上,這樣就能夠源碼跟打包後靜態文件在一個倉庫上。

9.2 GitHub Pages綁定域名

注意:若是GitHub Pages綁定域名,那麼配置文件中的base參數則須要刪除,不然域名訪問會失敗。

一、 首先須要購買一個域名,好比在阿里雲購買域名。
二、 域名須要實名認證,若是域名不是解析到IP地址則不須要備案,如域名指向github Pages就不須要備案。
三、在域名設置裏面設置解析記錄(以阿里雲域名爲例):

3.1 記錄類型:CNAME - 將域名指向另一個域名
3.2 主機記錄: 按提示輸入,通常填 @(直接解析成yuming.com)或 *(泛解析,匹配其餘全部域名 *.yuming.com)
3.3 記錄值:github帳戶的本身域名,如:user.github.io
3.4 解析線路:默認
3.5 TTL:默認

四、在項目裏面建立一個CNAME文件,裏面放入域名。
在上面的deploy.sh部署腳本中加入echo 'yuming.' > CNAME

# 生成靜態文件
vuepress build .

# 發佈到自定義域名
echo "把域名放到CNAME文件中"
echo 'yuming.com' > CNAME

# 進入生成的文件夾
cd ./.vuepress/dist

10. 在vuepress主題基礎上修改主題功能

10.1 導出默認主題

vuepress 0.14版本能夠把默認主題使用以下命令複製出來。
若是你的項目名稱是press,在press同級目錄下,終端輸入以下命令:

vuepress eject press

 DONE  Copied default theme into /Users/用戶名/tmp/press/.vuepress/theme.

這個命令來將默認主題的源碼複製到press目錄下的.vuepress/theme文件夾下,從而能夠對默認主題進行任意的修改。須要注意的是一旦 eject,即便升級 VuePress 你也沒法再得到 VuePress 對默認主題的更新。
clipboard.png

10.2 設置側邊欄當前頁面可收起、展開

最終效果:

clipboard.png

修改的代碼以下:

一、在導出的主題目錄中(.vuepress/theme/)找到Sidebar.vue文件,修改以下對應內容;

<template>
    <ul class="sidebar-links" v-if="items.length">
      <!-- 這裏修改了 -->
      <li v-for="(item, i) in items" :key="i" v-on:click="fileName($event.target)">
        <!-- SidebarGroup裏面加一個屬性chapter -->
        <SidebarGroup
          v-if="item.type === 'group'"
          @toggle="toggleGroup(i)"
          :chapter="chapter"
        />
        <!-- 這裏修改了 -->
        <SidebarLink v-else :item="item" :chapter="chapter"/>
      </li>
    </ul>
</template>

<script>
export default {
  // data方法修改爲以下
  data () {
    let h = '';
    if (typeof window !== 'undefined') {
      h = window.location.href
    }
    return {
      openGroupIndex: 0,
      href: h,
      chapter: true, // 菜單欄是否展開, true:展開, false:收起
      oneLevelkey: null, // 頁面菜單的key
    }
  },
  // created方法裏面添加一行代碼
  created () {
    this.refreshIndex()
    // 設置當前的頁面菜單key,用於菜單的展開、收縮
    this.setOneLevelkey();
  },
  // 在methods裏面添加4個新方法
  methods: {
    // 設置當前的頁面菜單key,用於菜單的展開、收縮
    setOneLevelkey () {
      let urlPath = '';
      // vuepress編譯項目的時候找不到location, 加個判斷
      if (typeof window !== 'undefined') {
        urlPath = decodeURIComponent(window.location.pathname);
      }
      this.items.forEach(element => {
        if (urlPath === element.path) {
          this.oneLevelkey = element.key;
        } else if (element.type === 'group') {
          element.children.forEach( e => {
            if (urlPath === e.path) {
              this.oneLevelkey = e.key;
            }
          })
        }
      });
    },
    // 點擊側邊欄標題連接
    fileName (a, time = 50) {
        // 延遲執行的目的是爲了把菜單渲染結束後在操做
        setTimeout(this.fileName2,time, a, time);
    },
    fileName2 (a, time) {
      var nextSibling = a.nextSibling;
      // 爲了防止在操做dom前ul尚未渲染,多進行幾回重試
      if (!a.nextSibling && time === 50) {
        this.fileName(a, 100)
      } else if (!a.nextSibling && time === 100) {
        this.fileName(a, 300)
      } else if (!a.nextSibling && time === 300) {
        this.fileName(a, 600)
      } else if (!a.nextSibling) {
        // 確實沒有子菜單,試了這麼多遍了, 若是卡了那沒辦法
        // 設置當前的頁面菜單key,用於菜單的展開、收縮
        this.setOneLevelkey();
      }
      // 點擊沒有子標題時 nextSibling === null,點擊的是分組側邊欄時 nextSibling === #text
      // 當點擊的標題有子標題時,才收縮標題
      if (nextSibling && nextSibling.tagName === 'UL') {
        // setTimeout(this.changeStyle,5, a.nextSibling, a.innerText);
        this.changeStyle(a.nextSibling, a.innerText);
      }
    },
    // 切換二級菜單
    changeStyle (b, aInnerText) {
      if (b.offsetHeight && b.offsetHeight > 0) {
        // 展開狀態, 收起菜單
        b.style.height = '0';
        b.style.overflow = 'hidden';
        this.items.forEach(element => {
          // 若是點擊的是頁面菜單標題
          if (aInnerText === element.title) {
            this.isOneLevel(b, element, false);
          } else if (element.type === 'group') {
            element.children.forEach( e => {
              if (aInnerText === e.title) {
                this.isOneLevel(b, e, false);
              }
            })
          }
        });
      } else {
        // 收起狀態,展開菜單
        b.style.height = 'auto';
        b.style.overflow = 'inherit';
        // 點擊的是頁面標題菜單 才展開
        this.items.forEach(element => {
          if (element.title === aInnerText) {
            this.chapter = true;
          } else if (element.type === 'group') {
            element.children.forEach( e => {
              if (e.title === aInnerText) {
                this.chapter = true;
              }
            })
          }
        });
      }
    },

    // 判斷點擊的是不是頁面標題菜單
    isOneLevel (b, element, chapter) {
      if (this.oneLevelkey !== element.key) {
        // 點擊的是不一樣頁面標題, 應該展開菜單
        b.style.height = 'auto';
        b.style.overflow = 'inherit';
        // 設置箭頭爲展開狀態
        this.chapter = true;
        // 設置選中的頁面標題的key
        this.oneLevelkey = element.key;
      } else if (this.oneLevelkey === element.key) {
        // 點擊的是同一個頁面標題,則收起菜單
        this.chapter = false;
      }
    },
  }
}
</script>

二、在導出的主題目錄中(.vuepress/theme/)找到SidebarLink.vue文件,修改以下對應內容;

<script>
export default {
  // props裏面添加一個chapter屬性
  props: ['item', 'chapter'],
  // render裏面的props添加一個chapter
  render (h, { parent: { $page, $site, $route }, props: { item, chapter }}) {
    // use custom active class matching logic
    // due to edge case of paths ending with / + hash
    const selfActive = isActive($route, item.path)
    // for sidebar: auto pages, a hash link should be active if one of its child
    // matches
    // item.type === 'auto' 是配置文件中設置themeConfig.sidebar = 'auto' 
    // 打開的是當前的頁面標題
    const active = item.type === 'auto'
      ? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
      : selfActive
    // renderLink方法添加chapter, true兩個參數
    const link = renderLink(h, item.path, item.title || item.path, active, chapter, true)
    const configDepth = $page.frontmatter.sidebarDepth != null
      ? $page.frontmatter.sidebarDepth
      : $site.themeConfig.sidebarDepth
    const maxDepth = configDepth == null ? 1 : configDepth
    // 是否在配置文件中設置themeConfig.displayAllHeaders = true
    const displayAllHeaders = !!$site.themeConfig.displayAllHeaders
    if (item.type === 'auto') {
      // item.type === 'auto' 是配置文件中設置themeConfig.sidebar = 'auto'
      return [link, renderChildren(h, item.children, item.basePath, $route, maxDepth)]
    } else if ((active || displayAllHeaders) && item.headers && !hashRE.test(item.path)) {
      // 側邊欄展開的狀態
      const children = groupHeaders(item.headers)
      return [link, renderChildren(h, children, item.path, $route, maxDepth)]
    } else {
      return link
    }
  }
}

// renderLink方法添加兩個參數:chapter, oneLevel
function renderLink (h, to, text, active, chapter, oneLevel) {
  return h('router-link', {
    props: {
      to,
      activeClass: '',
      exactActiveClass: ''
    },
    class: {
      // 可收縮菜單左邊的指示箭頭
      'one-level': oneLevel,    // 箭頭樣式
      'one-level-active': active && chapter && oneLevel,    // 箭頭向下樣式
      active,
      'sidebar-link': true
    }
  }, text)
}

</script>

<style lang="stylus">
// 在樣式末尾添加以下樣式
.one-level
  position relative
  &:before
    content ''
    border-top 1px solid
    border-right 1px solid
    position absolute
    left: 0px;
    top: 10px;
    height: 9px;
    width: 9px;
    transform: rotate(45deg);
  .sidebar-group &
    &:before
      left: 8px;
.one-level-active
  &:before
    left: 4px;
    transform: rotate(135deg);
  .sidebar-group &
    &:before
      left: 12px;
</style>

三、在導出的主題目錄中(.vuepress/theme/)找到SidebarGroup.vue文件,修改以下對應內容;

<template>
  <div
    :class="{ first, collapsable }"
  >
    <DropdownTransition>
      <ul
        v-if="open || !collapsable"
      >
        <li v-for="child in item.children">
          // 這一行添加一個chapter參數, 大約在26行
          <SidebarLink :item="child" :chapter="chapter"/>
        </li>
      </ul>
    </DropdownTransition>
  </div>
</template>

<script>
export default {
  // props裏面添加一個chapter屬性, 大約第39行
  props: ['item', 'first', 'open', 'collapsable', 'chapter'],
}
</script>

保存後,重啓vuepress服務便可。

10.3 設置側邊欄可收起、展開

最終效果以下圖:
clipboard.png

修改的代碼以下:

一、在導出的主題目錄中(.vuepress/theme/)找到SidebarButton.vue文件,修改以下對應內容;

<style lang="stylus">
// sidebar-button中,刪除 display none, 添加cursor pointer
.sidebar-button
  // display none
  cursor pointer
</style>

修改此文件的目的是在頁面左上角顯示展開、收縮的按鈕。

二、在導出的主題目錄中(.vuepress/theme/)找到Navbar.vue文件,修改以下對應內容;

<style lang="stylus">
// 在.navbar中添加padding-left 4rem
.navbar
  position relative
  padding-left 4rem
</style>

修改此文件的目的是在頁面左上角給側邊欄按鈕添加位置。

三、
在導出的主題目錄中(.vuepress/theme/)找到Layout.vue文件,修改以下對應內容;

<script>
export default {
  methods: {
    // 在toggleSidebar方法裏面添加一行代碼
    toggleSidebar (to) {
      // 這裏加一行代碼
      this.switchSidebar();
    },

    // 添加一個新方法: 顯示隱藏側邊欄
    switchSidebar() {
        // 側邊欄
        let sidebar = document.querySelector('#app .sidebar');
        // 內容區域
        let page = document.querySelector('#app .page');
        if (!sidebar || !page) {
            // 沒獲取到元素不執行方法
            return;
        }
        if (window.screen.width < 719) {
            // 手機屏幕,把樣式恢復
            sidebar.style.width = '';
            page.style.paddingLeft = '';
            return;
        }
        if (sidebar.offsetWidth > 100) {
            // 側邊欄是展開狀態, 收起側邊欄
            sidebar.style.width = '0';
            page.style.paddingLeft = '0';
        } else {
            // 側邊欄是收起狀態,展開側邊欄
            sidebar.style.width = '20rem';
            page.style.paddingLeft = '20rem';
        }
    },

  }
}
</script>

這裏主要是添加了一個新方法,並在toggleSidebar方法裏面執行這個方法, 這裏的代碼主要是實現側邊欄按鈕的切換功能

參考資料

vuepress 0.4版本官方文檔:https://v0.vuepress.vuejs.org...
Front-matter 教程:https://hexo.io/zh-cn/docs/fr...
vuepress中實現代碼摺疊、高亮

相關文章
相關標籤/搜索