最近學了react
,一直想作一個項目,沒有什麼好的主意。由於本身也要租房住,就想到了租房App
這個idea,參考豆瓣租房小程序,着手了這樣一個簡陋的先後端項目😄。
👉在線demo點擊這裏
👉項目源碼點擊這裏,你能夠下載在本地運行,若是對你有幫助能夠點一下star
哈😁css
// 你可使用npm或yarn
yarn install
運行你的數據庫 // 必須!!!
yarn server // 運行服務器, 鏈接的數據庫在server目錄下的config.js裏配置
yarn start // 運行項目
複製代碼
react+react-router+react-redux
,用create-react-app
腳手架生成。UI方面採用Ant Design Mobile
👉官方地址。css
方案是css-in-js,採用style-jsx
,👉 github地址,可參考掘金上的一篇文章👉點擊這裏。適配
問題,採用vm/vh
適配,具體一樣能夠參考掘金的👉這篇文章。run eject
彈出,因而用了react-app-rewired
改寫配置,這樣就不用彈出命令了。👉 github地址iconfont SVG
處理 focus
事件不能喚起鍵盤,安卓下能夠。爲了有個較好的用戶體驗,我在登陸,搜索
頁面打開時,讓輸入框自動focus
喚起鍵盤,經IOS
真機實踐,只能觸發focus
事件,可是不會喚起鍵盤,安卓
正常。查閱資料後是IOS
作的限制,(IOS
還有和音頻、視頻不能自動播放的限制)。須要用戶主動點擊輸入框後,才能夠喚起鍵盤。下一次從新打開就能自動喚起鍵盤了,很坑的一點😒!目前無解🙄redux
我用redux
(也可用react
的新context api
)解決,所以在路由方面也用了react-redux-router
,但已不維護,改成connect-react-router
github點這裏。思路是首次獲取房源列表,而後存入redux
中,下次打開的時候,從redux
中獲取。熱加載
後不能保存redux
中的狀態。解決方法:在store
中,添加如下代碼, 詳細看這裏if (module.hot) {
// Reload reducers
module.hot.accept('./reducers', () => {
store.replaceReducer(connectRouter(history)(rootReducer));
});
}
複製代碼
react-loadble
加載項目中的搜索頁面,會有搜索input
的placeholder
顯示不全的問題,初次打開會有問題,第二次打開沒有問題,以下圖。 在dev
環境下不能重現,生產環境
下會有問題。該組件爲Ant Design Mobile
的searchBar
。
110px
,而錯誤的時候則才80px
。暫時解決方法:移除該路由懶加載,直接加載😏loading
提示ajax
視狀況添加loading
提示,添加CSS3
動畫,使交互更加友好。koa2
+koa-router
+mongodb
+jsonWebToken
。最主要的是須要注意異步和異常處理的問題。Mongoose
來操做。Mongoose
是在node.js異步環境下對mongodb
進行便捷操做的對象模型工具。更多詳細說明請看官方文檔:👉點擊這裏http
庫是axios
。node-schedule
。github:👉點擊這裏cheerio
,它的用法十分簡單。const cheerio = require('cheerio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')
複製代碼
這裏咱們就能夠經過$(selector)
,像jquery
同樣的方式取到頁面的元素。官方文檔:👉點擊這裏前端
整個爬取的流程:node
5000
條數據),若是超過,則執行刪除,反之跳過。0.00am
開始爬取=>
爬取列表頁面=>
存入數據庫=>
若是失敗,不會爬取該條tid注意:豆瓣會限制一個時段內Ip的訪問次數,所以須要咱們作一些調整。react
// sleep
function sleep(time = 0) {
return new Promise(resolve => {
setTimeout(resolve, time);
});
}
// 更新數據庫函數
async updateTopic(tid, resolve, reject) {
// 睡眠
await sleep(Math.ceil(Math.random() * 50 * 1000) + 5000);
// 開始更新
await this.fetchDetail(tid).then(houseInfo => {...});
}
複製代碼
user-agent
。項目中是有個user-agent
列表👉查看代碼,每次請求都帶上隨機中的一個。這裏我是一次性插入多條數據,用到的api
以下jquery
db.Houses.insertMany([your array data])
複製代碼
須要注意的是部分路由(須要用戶登陸後才能夠訪問的接口)header
中須要傳遞token
才能訪問,所以添加路由中間件校驗,經過校驗
後才容許訪問。詳細代碼查看這裏。關鍵代碼以下👇ios
const jwt = require('jsonwebtoken');
const token = ctx.header['x-token'];
if(token){
解析token獲得用戶信息
進入下一個中間件
}else {
返回錯誤須要傳遞token
}
複製代碼
開始設計數據庫的時候,設置價格字段prices
是數組,後以爲字符串就能夠了。因而在原數據庫的基礎上修改數據格式及字段名prices
=>price
nginx
db.getCollection('houses').find().forEach(function(item){
db.getCollection('houses').update({_id:item._id},{$set:{prices: ''+item.prices}})
})
複製代碼
// 如將字段"prices"改成"price"
db.getCollection('houses').update({},{$rename:{'prices':'price'}}, false, true)
複製代碼
// db.copyDatabase(<from_dbname>, <to_dbname>, <from_hostname>)
db.copyDatabase('douban-house', 'douban-test')
複製代碼
// 大於 exists=1 小於exists=0
db.getCollection('houses').find({'imgs.n':{'$exists':1}})
複製代碼
// $ne=> not equal
db.getCollection('houses').find({'contact':{$ne:null}})
複製代碼
db.getCollection('houses').find({'tid':{$in:['這裏是數組','例如id1','2']}})
複製代碼
另外:插入字段數字Number Int
類型的數據會存儲爲Double
類型,會帶有小數點,例如存的是10
,存進數據庫以後會變成10.0
,能夠用NumberInt
或者NumberLong
來存儲git
db.houses.insert({"tid": NumberInt(666)})
複製代碼
爬蟲爬取貼子的時候,會爬到相同的貼子,而咱們是不須要這些重複的。這裏的問題是在插入重複值的時候,出現錯誤以後不會繼續插入剩下的數據,這是很坑的一點。下面是解決方法:github
mongodb
的惟一索引值,在設置的時候也遇到很多的坑,查了不少資料,總結相關的api
const housesSchema = new mongoose.Schema({
tid: String, //我這裏設置的惟一索引是每條貼子的id號
...省略
})
housesSchema.index({ tid: 1 }, { unique: true });
複製代碼
insert
仍是insertMany
, 他們的api
以下db.collection.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
}
)
複製代碼
這裏須要注意的是`ordered`這個參數, 這是一個可選參數,官方解釋以下
複製代碼
Optional. A boolean specifying whether the mongod instance should perform an ordered or unordered insert. Defaults to true.web
大意就是指定mongod實例是否應執行有序插入。默認爲```true```。
**重點是:**當有序插入的時候,若是出現了錯誤,程序會停下當前的插入,不執行插入剩餘的數據。只有當無序插入,也就是設置了```ordered: false```,當出現錯誤以後,纔會把剩下的繼續插入。官方說明以下:
> Excluding Write Concern errors, ordered operations stop after an error, while unordered operations continue to process any remaining write operations in the queue.
官方文檔連接:👉[點擊這裏](http://docs.mongodb.com/manual/reference/method/db.collection.insertMany)
複製代碼
package.json
中添加proxy
字段, 這裏假設http://localhost:3003
就是咱們的後臺服務器, http://localhost:3000
是react開發時候的服務器 如:在項目中訪問http://localhost:3000/api/house/125048127
就會代理到http://localhost:3003/api/house/125048127
, 就沒有跨域問題了"proxy": {
"/api": {
"target": "http://localhost:3003"
}
}
複製代碼
location /api/ {
proxy_pass http://localhost:3003;
}
複製代碼
有時候提交了錯誤的代碼又想回退版本,就須要回退遠程git
倉庫的代碼,再從新提交。 👉更多用法參考這裏
git reflog // 查看提交列表, 如我須要撤回到第二條提交記錄,也就是紅線下的那條
git reset --soft 3a2a12d // 這裏的參數--soft表示保留本地修改記錄, --hard 表明保存本地的記錄,若是是--hard 則會清空本地修改記錄,也就是你修改的都沒有了!!切記!!!
git push -f //強制推送到遠程分支
複製代碼