摘要:?jiǎn)雾?yè)博客應(yīng)用編寫(xiě)總結(jié)很久之前就想寫(xiě)一個(gè)博客應(yīng)用在一開(kāi)始想要直接用和模板直接寫(xiě)但是暑假一開(kāi)始的時(shí)候不小心入了的坑所以就一不做二不休直接用寫(xiě)那既然用了不寫(xiě)個(gè)單頁(yè)應(yīng)用也過(guò)意不去了不前前后后寫(xiě)了將近兩個(gè)星期現(xiàn)在看來(lái)這其實(shí)是一個(gè)很容易的應(yīng)用但是鑒于
React-Express單頁(yè)博客應(yīng)用編寫(xiě)總結(jié)
很久之前就想寫(xiě)一個(gè)博客應(yīng)用.
在一開(kāi)始想要直接用express和ejs模板直接寫(xiě), 但是暑假一開(kāi)始的時(shí)候不小心入了react的坑, 所以就一不做二不休直接用react寫(xiě). 那既然用了react, 不寫(xiě)個(gè)單頁(yè)應(yīng)用也過(guò)意不去了...(不
前前后后寫(xiě)了將近兩個(gè)星期, 現(xiàn)在看來(lái)這其實(shí)是一個(gè)很容易的應(yīng)用. 但是鑒于是第一次用react, 對(duì)于nodejs也不是特別熟悉, 所以走了不少冤枉路. 其中也有很多次覺(jué)得想放棄, 不過(guò)最終還是寫(xiě)下來(lái)了. 雖然還是有不少瑕疵, 不過(guò)也算給自己一個(gè)交代吧.
個(gè)人博客網(wǎng)站的地址為: harryfyodor.tk
下面會(huì)從幾個(gè)方面把我整個(gè)編寫(xiě)的過(guò)程的一些經(jīng)驗(yàn)記錄下來(lái), 主要是記錄自己的學(xué)習(xí)過(guò)程, 編寫(xiě)中遇到的困難以及解決, 以及一些學(xué)習(xí)/復(fù)習(xí)資料的整理分享. 也希望給各位和我一樣的初學(xué)者一點(diǎn)點(diǎn)借鑒的經(jīng)驗(yàn).
(個(gè)人感覺(jué)比較好的學(xué)習(xí)方式就是自己看資料(文檔和博客)然后寫(xiě)自己的一個(gè)小應(yīng)用, 而不是跟著某一個(gè)教程從頭到尾過(guò)一遍, 雖然不得不承認(rèn), 后者學(xué)起來(lái)的感覺(jué)很爽, 而且也更清晰. 但是不好的地方就是技術(shù)棧不完全匹配的時(shí)候就會(huì)很頭疼...)
下面是目錄:
前端 (包括react, redux, css-module等)
后端 (包括express, mongodb)
前后端 (包括fetch, jwt)
其他 (包括webpack, 優(yōu)化等)
下面直接進(jìn)入正題.
第一部分 前端 1, reactreact的學(xué)習(xí)根據(jù)官方文檔, 主要是理解一下幾個(gè)方面的內(nèi)容:
構(gòu)建模塊的方法. 用了推薦es6的class的方法而非createClass.
如何導(dǎo)入導(dǎo)出模塊. es6的import和export.
jsx的編寫(xiě). 不是必要的, 官網(wǎng)推薦. 感覺(jué)其中用上es6模板字符串, map方法會(huì)很方便很多~
props, state, refs的相關(guān)概念以及使用. 單向數(shù)據(jù)流中, 父組件給子組件傳遞數(shù)據(jù)通過(guò)props, 子組件給父組件傳遞數(shù)據(jù)用回調(diào)函數(shù). 后者的實(shí)現(xiàn)是通過(guò)父組件把一個(gè)函數(shù)傳到子組件中, 這個(gè)函數(shù)里面有可以有this.setState(收到子組件的數(shù)據(jù)后立刻渲染), 然后子組件調(diào)用傳進(jìn)來(lái)的函數(shù), 通過(guò)這個(gè)函數(shù)把參數(shù)傳給父組件.
掌握connect組件的使用方法. 把state數(shù)據(jù)和dispatch傳進(jìn)組件中.
生命周期. 在這個(gè)博客SPA應(yīng)用里用了componentDidMount和componentWillReceiveProps, 前者可用于初始化的渲染以及異步請(qǐng)求的發(fā)起, 后者用于接收到新的數(shù)據(jù)時(shí)的再次渲染, 把異步的結(jié)果渲染出來(lái). 因此一個(gè)組件(涉及到異步)是這樣工作的: 調(diào)用組件 -> 組件渲染之前發(fā)起異步請(qǐng)求 -> 第一次渲染,沒(méi)有數(shù)據(jù)的頁(yè)面 -> 接收到異步發(fā)回來(lái)的數(shù)據(jù) -> 重新渲染, 有數(shù)據(jù)的頁(yè)面. 代碼如下, 基本也是按照這種數(shù)據(jù)流向的方法來(lái)的(不知道是不是最好的方案, 但是感覺(jué)很方便).
class Archive extends React.Component { constructor(props) { super(props); this.displayName = "Archive"; this.state = { articles: [] } } componentDidMount() { this.props.actions.getTitles({ type: "ARCHIVE" }) } componentWillReceiveProps(nextProps) { this.setState({ articles: nextProps.getTitles.articles }) } render() { return ({/*這里是相關(guān)的渲染articles的操作, 注意要把[]的情況也考慮到*/}) }
}
export default Archive
配合好setState和生命周期, 運(yùn)用好父子組件之間的數(shù)據(jù)傳遞能夠很好地完成各種異步渲染.
2, redux理解redux主要是要理解action, reducer, middleware等概念. 個(gè)人感覺(jué)redux的官方文檔簡(jiǎn)直精彩, 例子也很豐富, 非常值得學(xué)習(xí). 這個(gè)SPA博客里的action大部分是為了ajax獲取后端數(shù)據(jù)服務(wù)的. 下面選取了其中的一組, 功能是獲取多帶帶的文章. 對(duì)應(yīng)不同相應(yīng)狀態(tài)有不同的action. 這樣就可以把異步的每一個(gè)狀態(tài)記錄下來(lái), 使得數(shù)據(jù)的流向更加清晰. 具體有關(guān)異步請(qǐng)求的相關(guān)的內(nèi)容可以看我的上一篇文章.
export const singleRequest = () => { return { type: SINGLE_REQUEST } } export const singleSuccess = (article) => { return { type: SINGLE_SUCCESS, article: article } } export const singleFailure = () => { return { type: SINGLE_FAILURE } } export const getSingle = (day, title) => { return dispatch => { dispatch(singleRequest()) return fetch("/api/single", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ day: day, title: title }) }) .then(checkHttpStatus) .then(res => res.json()) .then(res => { if(res.ok) { dispatch(singleSuccess(res.article)) } else { dispatch(singleFailure()) } }) } }
至于在reducer中, 初始化state用了幾個(gè)標(biāo)識(shí). 比如下面的例子中, 初始化的reducer state 包含了isFetching, isFetched, fetchFailure這些標(biāo)志異步進(jìn)行的當(dāng)前狀態(tài)的信息. 傳入props之后可以很方便地進(jìn)行異步請(qǐng)求先后的設(shè)置. 比方說(shuō)一個(gè)異步要在另一個(gè)異步之后, 就可以通過(guò)讀取這幾個(gè)數(shù)值完成. (第二個(gè)異步一定要在第一個(gè)的isFetched為true的時(shí)候才能發(fā)起)
const initialState = { isFetching: false, isFetched: false, fetchFailure: false, articles: [], count: 1 }
在整個(gè)應(yīng)用中需要用到中間件, 在應(yīng)用中用了thunk還有logger.
3, css-modules在博客應(yīng)用中css的引入用的是css-modules, 阮一峰大神的這篇文章講得算是完整了, 感興趣可以看一下~ 當(dāng)然有些部分也還是用了css in js的方法, 直接把css寫(xiě)到js里面, 主要是考慮到一些操作的方便, 比如點(diǎn)擊之后某一個(gè)標(biāo)簽display改變之類的.
第二部分 后端說(shuō)來(lái)慚愧, 后端大部分都是"抄"的, 之前看的一個(gè)教程是用express和ejs寫(xiě)的博客應(yīng)用, 而后端的操作大部分都比較接近. 主要就是根據(jù)接口路由處理數(shù)據(jù), 發(fā)送數(shù)據(jù), 通過(guò)數(shù)據(jù)庫(kù)api(這里是mongodb)讀取數(shù)據(jù)庫(kù)數(shù)據(jù). 所以最后寫(xiě)出來(lái)的和我原本看的那個(gè)教程有很大的相似之處. 我看的教程是這一個(gè), 非常棒, 感謝作者!!>o 1, express (nodejs)
關(guān)于express個(gè)人感覺(jué)比較重要的是處理配置以及路由兩個(gè)方面的問(wèn)題.
前者需要靠自己慢慢摸索, 比如要處理json需要用到bodyParser模塊, webpack一些中間件的配置等等, 可以拿redux官網(wǎng)還有上面提到的教程來(lái)參考一下.
后者主要是要了解express提供的各種方法, 以及一些有關(guān)res和req的相關(guān)操作等等.
有關(guān)數(shù)據(jù)庫(kù)的操作我也是參考上面的教程的...(oh..)基本對(duì)數(shù)據(jù)庫(kù)的增刪查改要掌握. 更多有關(guān)mongo的api原理等可以去看官網(wǎng)介紹.
3, 不足之處由于目標(biāo)不是專業(yè)后端, 所以后端做得比較粗糙. 不足之處有很多, 比如沒(méi)有擁抱es6(明明前端已經(jīng)擁抱), 比如還在若無(wú)其事地寫(xiě)著臭名昭著的回調(diào)金字塔等等等. nodejs需要加強(qiáng).
第三部分 前后端 1, 登錄 (JSON Web Token)有關(guān)登錄和登出開(kāi)始找了很多相關(guān)的實(shí)現(xiàn)方法, 在這篇文章的推薦下看了JWT實(shí)現(xiàn)方式. 簡(jiǎn)單來(lái)說(shuō)就是前端把密碼post到后端, 后端生成一個(gè)token然后發(fā)送到前端去. 前端把收到的token保存在localStorage中. 每次需要獲取一些保密的信息或者需要做一些修改的時(shí)候, 把這個(gè)token寫(xiě)在請(qǐng)求的headers里. 后端收到數(shù)據(jù)之后就會(huì)先驗(yàn)證一下token是否正確, 正確才允許操作.
headers: { "Content-Type": "application/json", "Accept": "application/json", "Authorization": `Bearer ${token}` }2,fetch (獲取數(shù)據(jù))
關(guān)于前后端交互這一點(diǎn)可以參考我寫(xiě)的上一篇文章. 后端把api暴露出來(lái)給前端, 前端通過(guò)ajax進(jìn)行數(shù)據(jù)的交互, 并把獲取到的數(shù)據(jù)渲染出來(lái). 操作上沒(méi)有難度, 只是要注意異步操作中redux要用中間件.
有關(guān)中間件還要去看點(diǎn)高階函數(shù)的基礎(chǔ)知識(shí), 不然無(wú)法正確理解.
沒(méi)有怎么認(rèn)真地看webpack的東西, 都是順手操起來(lái)直接用的...
說(shuō)實(shí)話, 第一次開(kāi)始看chrome的devtool的network的時(shí)候, 我被嚇得不輕...一個(gè)bundle文件5m大, PC端打開(kāi)之后真的是不忍直視. 后來(lái)上網(wǎng)找了一些webpack打包優(yōu)化的方向, 在這里記錄一下:
webpack的config文件里面不能有cheap-module-eval-source-map之類的devtool, 真的很大很大...
plugin如果不是必要的話也請(qǐng)刪去吧. 不過(guò)有兩個(gè)plugin可以在生產(chǎn)環(huán)境中用一下, 第一個(gè)是UglifyJsPlugin, 用于壓縮文件. 第二個(gè)是CommonsChunkPlugin, 這個(gè)具體下一點(diǎn)解釋.
適當(dāng)分塊. CommonsChunkPlugin用于把bundle分塊, 把可以放在緩存的, 常用的, 體積比較大的壓縮到vendor里面(比如react等). 后來(lái)又把babel-polyfill分開(kāi)另外加載了. 之前有看到code split, 就是直到需要用到該ui組件的時(shí)候才去加載, 想法好像不錯(cuò), 不過(guò)感覺(jué)改動(dòng)會(huì)比較大所以最后沒(méi)有做.
最后的文件大小其實(shí)也還是不小, 但是有了很好的改善. 關(guān)于前端優(yōu)化也是一個(gè)重要的話題.
2,markdown博客應(yīng)用寫(xiě)作用的是markdown. 原本想找一個(gè)現(xiàn)成的, 但是死活找不到合適的...最后直接用marked強(qiáng)行偽裝markdown編輯器...其實(shí)這很不安全, 但目前也沒(méi)有什么辦法...(draft.js貌似可以?)
總結(jié)總體來(lái)說(shuō), 這個(gè)博客其實(shí)實(shí)現(xiàn)起來(lái)沒(méi)有特別高的難度, 但是對(duì)于初學(xué)者來(lái)說(shuō)感覺(jué)真的挺不容易的. 之前聽(tīng)過(guò)這樣一句話--不要同時(shí)學(xué)幾樣?xùn)|西, 其實(shí)還真的有點(diǎn)道理...但是對(duì)于一些最佳實(shí)踐, 本身就要結(jié)合在一起才能發(fā)揮其最大的作用, 不一起學(xué)又怎么能行呢?(因此就陷入了大坑).
這個(gè)博客不完善的地方太多了, 特別是有關(guān)安全方面的問(wèn)題.不過(guò)現(xiàn)在還是先關(guān)注著前端吧.
希望這篇文章能夠給你一點(diǎn)點(diǎn)幫助.
最后上代碼博客代碼
(本人是初學(xué)者, 如果有什么說(shuō)得不對(duì), 不好的地方歡迎指出來(lái), 感激不盡!~互相學(xué)習(xí)!~)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86441.html
摘要:前言月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議那么今天我就把看過(guò)的一些學(xué)習(xí)資源主要是博客,博文推薦分享給大家。 1.前言 6月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多9月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了!一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議!那么今天我就...
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
摘要:另外,單頁(yè)應(yīng)用因?yàn)閿?shù)據(jù)前置到了前端,不利于搜索引擎的抓取。所以我們需要對(duì)自己的單頁(yè)應(yīng)用進(jìn)行一些優(yōu)化。 前言 最近秋招之余空出時(shí)間來(lái)按自己的興趣動(dòng)手做了一個(gè)項(xiàng)目,一個(gè)基于vue-cli3.0, vue,typescript的移動(dòng)端pwa,現(xiàn)在趁熱打鐵,將這個(gè)項(xiàng)目從開(kāi)發(fā)到部署整個(gè)過(guò)程記錄下來(lái),并將從這個(gè)項(xiàng)目中學(xué)習(xí)到的東西分享出來(lái),如果大家有什么意見(jiàn)或補(bǔ)充也可以在評(píng)論區(qū)提出。先介紹一下這個(gè)項(xiàng)...
閱讀 1479·2021-10-18 13:29
閱讀 2735·2021-10-12 10:18
閱讀 3596·2021-09-22 15:06
閱讀 2608·2019-08-29 17:09
閱讀 2799·2019-08-29 16:41
閱讀 1503·2019-08-29 13:48
閱讀 3238·2019-08-26 13:49
閱讀 3335·2019-08-26 13:34