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