個(gè)人博客開(kāi)發(fā)系列文章:
- 博客前端展示總結(jié):http://www.reibang.com/p/1348bcd1e716
- 后臺(tái)管理系統(tǒng)總結(jié):http://www.reibang.com/p/53c75476be44
- 服務(wù)端總結(jié):http://www.reibang.com/p/c25b5432d6f5
- Travis CI持續(xù)集成:http://www.reibang.com/p/4e7a06e18bd5
- 使用Nginx配置HTTPS和反向代理:http://www.reibang.com/p/c779e54c9f85
全棧開(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)碱妆。
- 博客地址:shirmy
- 項(xiàng)目地址:smile-blog-nuxt
主要技術(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ì)
- 首屏渲染慢,需要下載
JS
和CSS
文件 - 不利于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ì)比圖
如何實(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
的值為dark
或light
給--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.scss
和mixin.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ò)clipboardData
的setData()
方法在復(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');
`
}
]
}
}
參考文檔