全棧開(kāi)發(fā)—博客前端展示(Nuxt.js)

個(gè)人博客開(kāi)發(fā)系列文章:

全棧開(kāi)發(fā)—博客前端展示(Nuxt.js)

這個(gè)開(kāi)發(fā)的想法是這樣來(lái)的,大概兩個(gè)月前缀雳,騰訊云的工作人員打電話(huà)給我,說(shuō)我的域名沒(méi)有解析到騰訊云的服務(wù)器上啸澡,而且頁(yè)腳也沒(méi)有備案號(hào)云茸。我當(dāng)時(shí)就震驚了竞膳,居然會(huì)打電話(huà)給我刊侯,然而我的大學(xué)時(shí)代買(mǎi)的服務(wù)器已經(jīng)過(guò)期了...于是為了拯救我的域名,拯救我申請(qǐng)了很久的備案號(hào)休偶,決意要全棧打造一個(gè)屬于自己的博客系統(tǒng)碱妆。

主要技術(shù)

  • Nuxt.js
  • Axios
  • marked + highlight.js
  • scss

項(xiàng)目特點(diǎn)

  • 適配多個(gè)分辨率骤肛,移動(dòng)端到桌面端無(wú)縫切換
  • 支持白晝黑夜主題切換(試試點(diǎn)擊shirmy的太陽(yáng)或月亮)
  • 文章圖片懶加載
  • 評(píng)論秕豫、留言侮穿、搜索、點(diǎn)贊、多個(gè)作者
  • SSR服務(wù)端渲染(seo)

技術(shù)總結(jié)

什么是服務(wù)端渲染(server side render)验残?

服務(wù)端渲染則把Ajax請(qǐng)求放到服務(wù)端,頁(yè)面加載到瀏覽器或客戶(hù)端前就已經(jīng)把數(shù)據(jù)填充到頁(yè)面模板行程完整的頁(yè)面欧募。

優(yōu)勢(shì)

  • 減少首次http請(qǐng)求还栓,在服務(wù)端請(qǐng)求首屏數(shù)據(jù)辽聊,直接渲染html
  • 利于SEO通砍,網(wǎng)絡(luò)爬蟲(chóng)可以抓取到完整的頁(yè)面信息

劣勢(shì)

  • 服務(wù)端壓力大
  • 需要掌握從前端到服務(wù)端的開(kāi)發(fā)(多學(xué)點(diǎn)不好嗎虎忌?)

什么是客戶(hù)端渲染(client side render)?

客戶(hù)端渲染就是就是在客戶(hù)端通過(guò)Ajax請(qǐng)求獲取數(shù)據(jù)挑围,然后在客戶(hù)端生成DOM插入到html

優(yōu)勢(shì)

  • 前后端分離,各司其職
  • 局部刷新,無(wú)需重新刷新頁(yè)面
  • 服務(wù)器壓力小
  • 更好的實(shí)現(xiàn)各種前端效果

劣勢(shì)

  • 首屏渲染慢,需要下載JSCSS文件
  • 不利于SEO,爬蟲(chóng)抓取不到完整的頁(yè)面數(shù)據(jù)

SSR vs CSR

門(mén)戶(hù)網(wǎng)站、博客網(wǎng)站等需要SEO優(yōu)化的網(wǎng)站使用服務(wù)端渲染哑姚,管理后臺(tái)等內(nèi)部系統(tǒng)或不需要SEO優(yōu)化的網(wǎng)站使用客戶(hù)端渲染

對(duì)比圖

服務(wù)端渲染
前端渲染

如何實(shí)現(xiàn)白晝黑夜主題切換?

在這里谆奥,要使用CSS3變量配合scss進(jìn)行控制檐蚜,通過(guò)控制<body>標(biāo)簽的id來(lái)約束白晝或黑夜的顏色值,再給相應(yīng)的屬性加上transition屬性實(shí)現(xiàn)顏色切換時(shí)的過(guò)渡褐荷,請(qǐng)看下面的示例:

@mixin theme(
  $theme-primary
) {
  --theme-primary: #{$theme-primary}
}

body {
  &#light {
    @include theme(
      #theme-primary: #fff,
    )
  }

  &#dark {
    @include theme(
      #theme-primary: #000,
    )
  }
}

全局引入上面的scss文件棠赛,這樣就可以直接通過(guò)設(shè)置<body>標(biāo)簽的id的值為darklight--theme-primary賦予不同的顏色值,此時(shí)就能直接在需要應(yīng)用該顏色的元素上進(jìn)行如下設(shè)置:

.example-class {
  color: var(--theme-primary);
}

在我的博客shirmy中點(diǎn)擊月亮/太陽(yáng)即可看到效果商膊,亦可用同樣的方式定義多套主題色。

切換頁(yè)面改變頁(yè)面title

Nuxt內(nèi)置了head屬性配置闸溃,head配置直接修改根目錄下的nuxt.config.js文件就可以了昼扛,并且還內(nèi)置vue-meta插件塞颁,因此想要在不同頁(yè)面改變相應(yīng)的title,請(qǐng)看以下做法:

// nuxt.config.js
module.exports = {
  head: {
    // 組件中的 head() 方法返回的字符串會(huì)替換 %s
    titleTemplate: '%s | shirmy',
  }
}

// 文章詳情頁(yè) pages/article/_id.vue
export default {
  head() {
    return {
      title: this.article.title
    }
  }
}

如此一來(lái)毅糟,當(dāng)查看某篇文章詳情的時(shí)候就會(huì)觸發(fā)head()方法苟蹈,title顯示為article title | shirmy

切換頁(yè)面讓頁(yè)面滾動(dòng)保持在頂部

只要修改nuxt.config.js配置即可,并且可以根據(jù)傳入的參數(shù)做一些自定義的配置主到。

// nuxt.config.js
module.exports = {
  router: {
    scrollBehavior: function (to, from, savedPosition) {
      return { x: 0, y: 0 }
    }
  },
}

Nuxt中的fetch()

fetch()Nuxt中獨(dú)有的方法,它會(huì)在組件初始化前被調(diào)用轮纫,因此無(wú)法通過(guò)this獲取組件對(duì)象。比如進(jìn)入首頁(yè)或從首頁(yè)切換到歸檔頁(yè)虫几,在進(jìn)入頁(yè)面前會(huì)先執(zhí)行fetch()方法,為了異步獲取數(shù)據(jù)叨粘,fetch()方法必須返回Promise鼻弧,因此可以直接返回一個(gè)Promise或者使用async await(async await其本質(zhì)就是返回Promise)稿存。

該方法不會(huì)設(shè)置組件的數(shù)據(jù)袖迎,如果想要設(shè)置組件的數(shù)據(jù)燕锥,或者使用context上下文榴芳,可以使用asyncData窟感。

export default {
  // 雖然無(wú)法通過(guò) this.$nuxt.$route 獲取路由參數(shù)躏嚎,但是可以通過(guò) params 來(lái)獲取
  async fetch({ store, params }) {
    await store.dispatch('about/getAuthor', params.id)
    await store.dispatch('about/getArticles', {
      authorId: params.id,
      page: 0
    })
  }
}

這樣就能確保內(nèi)容已經(jīng)渲染好再下載到瀏覽器仇参,如果使用mounted等生命周期鉤子仰泻,則是在頁(yè)面下載到瀏覽器后再獲取數(shù)據(jù)泡挺,起不到SSR服務(wù)端渲染的效果辈讶。

style-resource

為了方便統(tǒng)一管理scss變量,通常會(huì)在目錄中創(chuàng)建variables.scssmixin.scss娄猫,但是我們寫(xiě)的vue文件這么多贱除,如果都要一個(gè)個(gè)導(dǎo)入豈不是吃力不討好生闲,這時(shí)可以借助style-resource

npm install -S @nuxtjs/style-resources

修改nuxt.config.js文件:

// nuxt.config.js
module.exports = {
  styleResources: {
    scss: ['./assets/scss/variables.scss', './assets/scss/mixin.scss']
  }
},

圖片懶加載

圖片懶加載的關(guān)鍵是使用IntersectionObserver,IE瀏覽器不兼容月幌,需要使用polyfill碍讯。該WebAPI用于監(jiān)聽(tīng)元素是否出現(xiàn)在頂級(jí)文檔視窗中。

通過(guò)這個(gè)WebAPI扯躺,我們可以把<img>標(biāo)簽的src屬性地址先掛在data-src屬性上捉兴,當(dāng)該元素出現(xiàn)在視窗時(shí)就會(huì)觸發(fā)IntersectionObserver的的回調(diào)方法,此時(shí)再給<img>標(biāo)簽的src屬性賦予先前掛在data-src上的地址

復(fù)制時(shí)攜帶轉(zhuǎn)載聲明

監(jiān)聽(tīng)copy事件录语,然后通過(guò)getSelection()方法獲取復(fù)制的內(nèi)容倍啥,在通過(guò)clipboardDatasetData()方法在復(fù)制內(nèi)容上加上轉(zhuǎn)載信息:

if (process.env.NODE_ENV === 'production') {
  const copyText = `

---------------------
作者:shirmy
鏈接:${location.href}
來(lái)源:https://www.shirmy.me
商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處澎埠。`

  document.addEventListener('copy', e => {
    if (!window.getSelection) {
      return
    }
    const content = window.getSelection().toString()

    e.clipboardData.setData('text/plain', content + copyText)
    e.clipboardData.setData('text/html', content + copyText)
    e.preventDefault()
  })
}

markdown防止XSS攻擊

如果讀者在評(píng)論中輸入<script>alert('xss')</script>虽缕,那么進(jìn)入文章詳情頁(yè)時(shí)就會(huì)觸發(fā)這段代碼,這時(shí)候蒲稳,我們就需要把script過(guò)濾掉彼宠,當(dāng)然XSS還有許多類(lèi)似的方式,但是萬(wàn)變不離其宗

在這里弟塞,我借助了DOMPurify

npm install dompurify -S
DOMPurify.sanitize(html)

使用谷歌分析服務(wù)

首先進(jìn)入官網(wǎng)Google 統(tǒng)計(jì)分析服務(wù)凭峡,并注冊(cè)你的賬號(hào),得到一個(gè)格式如GA_MEASUREMENT_ID的媒體資源ID

然后直接修改nuxt.config.js决记,當(dāng)然也可以自定義(gtag.js開(kāi)發(fā)指南):

// nuxt.config.js
module.exports = {
  head: {
    // 其它配置...
    script: [
      // 其它配置...
      {
        async: 'async',
        type: 'text/javascript',
        // GA_MEASUREMENT_ID 替換為你剛剛注冊(cè)得到的媒體資源ID
        src: 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID'
      },
      {
        // Global site tag (gtag.js) - Google Analytics
        type: 'text/javascript',
        // GA_MEASUREMENT_ID 替換為你剛剛注冊(cè)得到的媒體資源ID
        innerHTML: `
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());

          gtag('config', 'GA_MEASUREMENT_ID');
        `
      }
    ]
  }
}

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摧冀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子系宫,更是在濱河造成了極大的恐慌索昂,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扩借,死亡現(xiàn)場(chǎng)離奇詭異椒惨,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)潮罪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)康谆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人嫉到,你說(shuō)我怎么就攤上這事沃暗。” “怎么了何恶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵孽锥,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)惜辑,這世上最難降的妖魔是什么唬涧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮盛撑,結(jié)果婚禮上碎节,老公的妹妹穿的比我還像新娘。我一直安慰自己撵彻,他們只是感情好钓株,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布实牡。 她就那樣靜靜地躺著陌僵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪创坞。 梳的紋絲不亂的頭發(fā)上碗短,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音题涨,去河邊找鬼偎谁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛纲堵,可吹牛的內(nèi)容都是我干的巡雨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼席函,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼铐望!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起茂附,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤正蛙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后营曼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體乒验,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蒂阱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锻全。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡录煤,死狀恐怖虱痕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辐赞,我是刑警寧澤部翘,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站响委,受9級(jí)特大地震影響新思,放射性物質(zhì)發(fā)生泄漏窖梁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一夹囚、第九天 我趴在偏房一處隱蔽的房頂上張望纵刘。 院中可真熱鬧,春花似錦荸哟、人聲如沸假哎。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舵抹。三九已至,卻和暖如春劣砍,著一層夾襖步出監(jiān)牢的瞬間惧蛹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工刑枝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留香嗓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓装畅,卻偏偏與公主長(zhǎng)得像靠娱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子掠兄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容