點擊連接獲取博客項目精簡模板源碼←
在上文 VuePress博客搭建筆記(一)簡單上手
中,我簡單闡述了VuePress博客搭建的過程,並對其中的一些問題進行分析記錄,
包括首頁,側邊欄,導航欄,瀏覽器書籤引入,掛載githubPage等等。html
本文將圍繞着博客的個性化配置做一個整理。前端
首先引用官網的原文重申一次VuePress博客搭建的過程:vue
Start
As Easy as 1, 2, 3
# install yarn global add vuepress@next # OR npm install -g vuepress@next # create a markdown file echo '# Hello VuePress' > README.md # start writing vuepress dev # build to static files vuepress build
VuePress的官網目前是存在兩個版本的,分別爲0.x版本和最新的1.x的alpha版本。
在實際開發中,我常常由於混淆版本而致使一些插件不能正常引入,固然這也是由於我對VuePress的使用還不熟練。
打開VuePress的官網,若是有下面綠色的Notice彈出,說明是1.x版本。node
若是是開發者,建議安裝最新版VuePress,體驗最新的輪子~git
yarn add vuepress -D # Install 0.x.x. yarn add vuepress@next -D # Install next.
與github關聯的頁腳連接和導航欄連接,github
/** * config.js * @type {{themeConfig: {lastUpdated: string, repoLabel: string, * docsDir: string, repo: string, editLinkText: string, * docsRepo: string, editLinks: boolean, docsBranch: string}}} */ module.exports = { // ... themeConfig: { // 假定是 GitHub. 同時也能夠是一個完整的 GitLab URL repo: 'https://github.com/Mulander-J/Wiki1001Pro.git', // 自定義倉庫連接文字。默認從 `themeConfig.repo` 中自動推斷爲 // "GitHub"/"GitLab"/"Bitbucket" 其中之一,或是 "Source"。 repoLabel: 'GitHub', // 如下爲可選的編輯連接選項 // 假如你的文檔倉庫和項目自己不在一個倉庫: docsRepo: 'https://github.com/Mulander-J/Wiki1001Dev', // 假如文檔不是放在倉庫的根目錄下: docsDir: 'docs', // 假如文檔放在一個特定的分支下: docsBranch: 'master', // 默認是 false, 設置爲 true 來啓用 editLinks: true, // 默認爲 "Edit this page" editLinkText: '博主通道__GitHub Private Repo !', // 文檔更新時間:每一個文件git最後提交的時間, lastUpdated: 'Last Updated' , } }
npm install @vuepress/theme-default@next
##複製node_modules/@vuepress/theme-default 文件夾 ##粘貼至.vuepress/ 下並改名爲theme Dev ├─── docs │ └── .vuepress // 配置目錄 │ │ ├── public // 靜態資源 │ │ ├── theme // 主題 │ │ │ ├── components // 組件 │ │ │ ├── global-components // 全局組件 │ │ │ ├── global-components // 全局組件 │ │ │ ├── layouts // 佈局(包括首頁在內) │ │ │ ├── styles // 樣式 │ │ │ ├── util // 工具 │ │ │ ├── index.js // 入口配置 │ │ │ ├── noopModule.js // 依賴注入 │ │ │ ├── package.json // 主題依賴 │ │ │ ├── README.md // 主題說明 │ │ └── config.js │ ├── FAQ // 求索模塊 │ ├── Store // 倉庫模塊 │ ├── Thought // 隨筆模塊 │ └── README.md // 博客首頁 └── package.json
npm run dev
關注控制檯輸出web
tip Apply theme located at G:\WorkSpace\WebStormWS\Wiki1001\Dev\docs\.vuepress\theme...
npm
若果控制檯能看到上面這句話或者頁面能正常渲染的話,就表示主題引入成功json
"C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" run dev --scripts-prepend-node-path=auto > wiki1001@1.0.0 dev G:\WorkSpace\WebStormWS\Wiki1001\Dev > vuepress dev docs wait Extracting site metadata... tip Apply theme located at G:\WorkSpace\WebStormWS\Wiki1001\Dev\docs\.vuepress\theme...
接下來就能夠對這份theme項目做修改了,segmentfault
它就是載負你的博客的一個簡單的VUe單頁面項目。
設置頁面滾動條爲漸變色&圓角樣式
參考
/*定義滾動條高寬及背景 高寬分別對應橫豎滾動條的尺寸*/ ::-webkit-scrollbar { width: 8px; height: 8px; border-radius: 10px; background-color: #F5F5F5; } /*定義滾動條軌道 內陰影+圓角*/ ::-webkit-scrollbar-track { border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); background-color: #F5F5F5; } /*定義滑塊 內陰影+圓角*/ ::-webkit-scrollbar-thumb { border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); border-radius: 10px; /* 線性漸變 */ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.44, rgb(60,186,146)), color-stop(0.72, rgb(253,187,45)), color-stop(0.86, rgb(253,187,45))); transition: 0.3s ease-in-out; } /*定義滑塊懸浮樣式*/ ::-webkit-scrollbar-thumb:hover{ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.44, rgb(253,187,45)), olor-stop(0.72, rgb(253,187,45)), color-stop(0.86, rgb(60,186,146))); transition: 0.3s ease-in-out; }
h1{ background-image: -webkit-linear-gradient(left, #22c1c3, #fdbb2d 25%, #22c1c3 50%, #fdbb2d 75%, #22c1c3); -webkit-text-fill-color: transparent; -webkit-background-clip: text; -webkit-background-size: 200% 100%; -webkit-animation: myGradientChange 4s infinite linear; animation: myGradientChange 4s infinite linear; } .description,.card h2{ background-image: -webkit-linear-gradient(left, #fdbb2d, #22c1c3 25%, #fdbb2d 50%, #22c1c3 75%, #fdbb2d); -webkit-text-fill-color: transparent; -webkit-background-clip: text; -webkit-background-size: 200% 100%; -webkit-animation: myGradientChange 4s infinite linear; animation: myGradientChange 4s infinite linear; } @keyframes myGradientChange { 0%{ background-position: 0 0;} 100% { background-position: -100% 0;} }
npm install @vuepress/plugin-back-top@next
// 複製node_modules/@vuepress/plugin-back-top/BackToTop.vue // 粘貼至.vuepress/theme/components <template> <div> <BackToTop></BackToTop> </div> </template> <script> import BackToTop from '../components/BackToTop.vue' export default { components: { BackToTop}, } </script>
複製一個Back To Top DOM節點同時修改 transition 爲 transition-group
<template> <transition-group name="fade"> <svg v-if="topShow" class="go-to-top" key="goTop" @click="scrollToTop" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 49.484 28.284" > <g transform="translate(-229 -126.358)"> <rect fill="currentColor" width="35" height="5" rx="2" transform="translate(229 151.107) rotate(-45)"/> <rect fill="currentColor" width="35" height="5" rx="2" transform="translate(274.949 154.642) rotate(-135)"/> </g> </svg> <svg v-if="endShow" class="go-to-top go-to-end" @click="scrollToEnd" key="goEnd" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 49.484 28.284" > <g transform="translate(-229 -126.358)"> <rect fill="currentColor" width="35" height="5" rx="2" transform="translate(229 151.107) rotate(-45)"/> <rect fill="currentColor" width="35" height="5" rx="2" transform="translate(274.949 154.642) rotate(-135)"/> </g> </svg> </transition-group> </template>
增長 變量 scrollEnd , endShow
方法 getScrollEnd() ,scrollToEnd()
<script> import debounce from 'lodash.debounce' export default { props: { threshold: { type: Number, default: 300 } }, data () { return { scrollTop: null, scrollEnd: null } }, mounted () { this.scrollTop = this.getScrollTop() this.scrollEnd = this.getScrollEnd() window.addEventListener('scroll', debounce(() => { this.scrollTop = this.getScrollTop() this.scrollEnd = this.getScrollEnd() }, 100)) }, methods: { getScrollTop () { return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0 }, getScrollEnd () { return document.documentElement.scrollHeight || document.body.scrollHeight || this.threshold }, scrollToTop () { window.scrollTo({ top: 0, behavior: 'smooth' }) this.scrollTop = 0 }, scrollToEnd () { window.scrollTo({ top: this.scrollEnd, behavior: 'smooth' }) this.scrollTop = this.scrollEnd } }, computed: { topShow () { return this.scrollTop > this.threshold }, endShow () { return (this.scrollEnd - this.scrollTop) > 3*this.threshold } } } </script>
增長置底按鈕樣式,z軸旋轉180度
<style lang='stylus' scoped> .go-to-top { cursor: pointer; position: fixed; bottom: 5rem; right: 2.5rem; width: 2rem; color: $accentColor; z-index: 1; } .go-to-end{ bottom: 2rem; transform: rotateZ(180deg); } .go-to-top:hover { color: lighten($accentColor, 30%); } @media (max-width: 959px) { .go-to-top { display: none; } } .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; } .fade-enter, .fade-leave-to { opacity: 0; } </style>
yarn add -D @vuepress/plugin-pwa # OR npm install -D @vuepress/plugin-pwa
//config,js module.exports = { // ... plugins: [ ['@vuepress/pwa', { serviceWorker: true, //指向自定義組件 popupComponent: 'MySWUpdatePopup', updatePopup: { message: "新的風暴已經出現", buttonText: "盤他" } }] ] }
serviceWorker的做用大體就頁面首次加載時會請求本地的serviceWorker.js去比對各個文件的版本號
若是不一致則提示用戶拉取更新
不過這個popup的默認樣式很醜😨,因此官方也提供了自定義popup的接口和教程
默認樣式,這是原始的...eh
這是官網給的模板 = = 阿咧?
這是個人...emmm..可還行呢,湊合用了。這個vue的logo還會動的,不算侵權吧😱...@Vue??
P.S.這個popup 的內容是我自定義寫的,不是官方在皮啊
參考
注意
v-if="enabled"
// 添加這一段指令,不然popup沒法消失
<SWUpdatePopup> <div v-if="enabled" slot-scope="{ enabled, reload, message, buttonText }" class="my-sw-update-popup"> {{ message }}<br> <button @click="reload">{{ buttonText }}</button> </div> </SWUpdatePopup>
yarn add -D @vuepress/plugin-google-analytics # OR npm install -D @vuepress/plugin-google-analytics
//config.js module.exports = { ... plugins: [ ['@vuepress/google-analytics', { ga: '*********'//你的Google Analytics ID }], ] }
google_analysis 會實時監控你的url,假若一個頁面有多個h2,h3標題,滑動滾動條致使url的變化也會被捕捉到。
參考
# Install leancloud's js-sdk npm install leancloud-storage --save # Install valine npm install valine --save
// Register AV objects to the global window.AV = require('leancloud-storage'); // Use import import Valine from 'valine'; // or Use require const Valine = require('valine'); new Valine({ el:'#vcomments', // other config })
//Page.vue <script> export default { mounted: function(){ // require window const Valine = require('valine'); if (typeof window !== 'undefined') { this.window = window window.AV = require('leancloud-storage') } new Valine({ el: '#vcomments' , appId: '',// your appId appKey: '', // your appKey notify:false, //郵箱通知,可關閉 verify:false, //反人類的算術驗證碼,建議關閉 avatar:'mm', //頭像,默認便可 visitor: true,//訪問計數 placeholder: 'just go go' }); } } </script>
Issue
無論地址欄怎麼變化,無論怎麼切頁面,評論內容不會隨地址欄變化而變化,即沒法同步。
Valine實例與leancloud-storage實例 在每次頁面加載時會向服務器發起
帶當前url參數的請求以獲取評論數據,而這個url參數每次都是同樣。
首先Valine 實例與 leancloud-storage 實例都在 mounted 鉤子中初始化或掛載至 window 對象上了,
當頁面 url 變化時,Page.vue 自己並無變化,只是它身上的<Content/>
內容變了,mounted沒有從新觸發,上面兩個實例也沒有改變。
P.S.血的教訓
不要在 md 文件中直接寫<Content/>
,請用其餘格式編譯它,不然會被vuepress識別爲組件而不斷加載陷入死循環。
[Vue warn]: Error in nextTick: "RangeError: Maximum call stack size exceeded" warn @ vue.runtime.esm.js?2b0e:601 vue.runtime.esm.js?2b0e:1832 RangeError: Maximum call stack size exceeded
Exp: 只是它身上的<Content/>內容變了, 只是它身上的`<Content/>`內容變了,
若是從新 init 兩個實例呢?
暫時沒法解決...emmm,欲知後事如何,請聽下回分解..
欸,應該沒有(三)了,等解決了直接寫在評論裏吧。
解決 Valine 不隨頁面刷新 , Page.vue 改動以下:
<script> import... export default { // 初始化Valine組件 mounted() { this.renderValine() }, watch :{ // 路由變化時從新初始化Valine組件 $route (a,b) { if(a.path!=b.path){ this.renderValine() } } }, methods: { // 生成評論組件的 Dom 元素 renderValine () { //由於此方法會構建dom節點,因此<template>中不須要再加相關dom元素 let $page = document.querySelector('.page') let vcomments = document.getElementById('vcomments') if(!vcomments){ vcomments = document.createElement('div') vcomments.id = 'vcomments' } if(this.$page.frontmatter.hideFooter){ // 若是forntmatter中標註'hideFooter:true'則不渲染評論組件,使得評論組件在各個頁面的顯示可控 vcomments.remove(); }else{ if ($page && !vcomments){ $page.appendChild(vcomments) }else{ $page = document.querySelector('.page') $page.appendChild(vcomments) } this.valine() } }, // 初始化valine實例 valine () { const Valine = require('valine') const leancloudStorage = require('leancloud-storage') // require window if (typeof window !== 'undefined') { window.AV = leancloudStorage } // 配置valine參數 new Valine({ el: '#vcomments' , appId: '',// your appId appKey: '', // your appKey notify:true, verify:false, visitor: true, avatar:'wavatar', placeholder: '春霄苦短,少女前進吧!' +'\n'+ '夜は短し歩けよ乙女!' +'\n'+ 'Yoru wa Mijikashi Arukeyo Otome!' +'\n'+ 'The Night is Short, Walk on Girl!', path: window.location.pathname }); }, }
點擊連接獲取博客項目精簡模板源碼←