前端路由&react-router使用姿勢
路由?
對於有過SPA開發經驗的人來說,路由這個名詞並不陌生,前端的路由和後端的路由在實現技術上不一樣,但是原理都是一樣的。在 HTML5 的 history API 出現之前,前端的路由都是通過 hash 來實現的,hash 能相容低版本的瀏覽器。它的 URI 規則中需要帶上 #。Web 服務並不會解析 hash,也就是說 # 後的內容 Web 服務都會自動忽略,但是 JavaScript 是可以通過 window.location.hash 讀取到的,讀取到路徑加以解析之後就可以響應不同路徑的邏輯處理。
簡單介紹AngularJs UI-Router路由?
如果你有過angularjs開發經驗,#並不陌生,angularjs有自己官方實現的路由體系,也有比較具有代表性的第三方巢狀路由機制UI-Router; 如下程式碼塊所示:
.state("main.list",angularAMD.route({
url : '/list/:params',//url &引數
views : {
"[email protected]" : angularAMD.route({
templateUrl : 'simple/view/main/html/main/Header.html',
controller:'HeadController',
controllerUrl:[ ****.js
]
}) ,
"[email protected]" : angularAMD.route({
templateUrl : 'simple/view/main/html/main/MenuModule.html',
controller : "MenuController",
controllerUrl:[ ****.js]
}),
"[email protected]":angularAMD.route({
templateUrl : 'simple/view/main/html/main/MainContent.html'
})
}
}))
state()函式的第一個引數就是路由,“main.list” 是一個巢狀路由機制,當頁面跳轉到 “main.list”路由下時會先載入 state(“main”,*)下的模組及其資源(html,js等),隨後載入state(”main.list”)下的模組和資源(html,js等),實現路由巢狀;
react-router?
-先上一段程式碼
<Router history={ hashHistory }>
<Route path='/' component={CoreLayout}>
<IndexRoute component={HomeView}/>
<Route path=”/HODE_ROUTE/:param“ component={HomeView}/>
<Route path=“ /AUDIT_ROUTE/:param" component={AuditView}/>
<Route path=“/CHART_ROUTE” component={ChartView}/>
</Route>
</Router>
react-router以jsx語法類似於DOM結構的形式實現router巢狀;與AngularJs 的UI-Router看似差別很大,實則思想雷同;
Angular的實現邏輯:
跳轉=》state=》module=》靜態資源(js,css,html)=》show(頁面展示)
react-router的實現邏輯:
跳轉=》path=》component=》靜態資源(js,css,html)=》show(頁面展示)
本文主要講react-router,下面簡單介紹react-router的使用姿勢:
react-router常用元件入門
- 巢狀路由
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Route>
</Router>
上面程式碼中,使用者訪問/repos時,會先載入App元件,然後在它的內部再載入Repos元件。
<App>
<Repos/>
</App>
子路由也可以不寫在Router元件裡面,單獨傳入Router元件的routes屬性
let routes = <Route path="/" component={App}>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Route>;
<Router routes={routes} history={browserHistory}/>
- path 屬性
Route元件的path屬性指定路由的匹配規則,看下面例子
<Route path="inbox" component={Inbox}>
<Route path="messages/:id" component={Message} />
</Route>
上面程式碼中,當用戶訪問/inbox/messages/:id時,會載入下面的元件。
<Inbox>
<Message/>
</Inbox>
- IndexRoute 元件
類似index.html ,預設載入元件,下面程式碼預設載入home元件
<Router>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="accounts" component={Accounts}/>
<Route path="statements" component={Statements}/>
</Route>
</Router>
現在,使用者訪問/的時候,載入的元件結構如下。
<App>
<Home/>
</App>
Redirect 元件
Redirect元件用於路由的跳轉,即使用者訪問一個路由,會自動跳轉到另一個路由。
<Route path="inbox" component={Inbox}>
{/* 從 /inbox/messages/:id 跳轉到 /messages/:id */}
<Redirect from="messages/:id" to="/messages/:id" />
</Route>
現在訪問/inbox/messages/5,會自動跳轉到/messages/5。
- Link
Link元件用於取代a標籤,生成一個連結,允許使用者點選後跳轉到另一個路由。它基本上就是a標籤的React 版本,可以接收Router的狀態。
- 表單處理
Link元件用於正常的使用者點選跳轉,但是有時還需要表單跳轉、點選按鈕跳轉等操作。這些情況怎麼跟React Router對接呢?
####第一種方法是使用browserHistory.push
handleSubmit(event) {
event.preventDefault()
const userName = event.target.elements[0].value
const repo = event.target.elements[1].value
const path = `/repos/${userName}/${repo}`
browserHistory.push(path)
}
${userName} 一種後端語言常用的表示式寫法,可在字串中取變數
handleSubmit(event) {
// ...
this.context.router.push(path)
},
第二種方法是使用context物件。
export default React.createClass({
// ask for `router` from context
contextTypes: {
router: React.PropTypes.object
},
handleSubmit(event) {
// ...
this.context.router.push(path)
},
})
多人協作開發router檔案管理??
一般一個專案都會有一個統一的router檔案,相當於一個router池,不同的請求,請求router池中所匹配的路徑,載入請求所需頁面。 but 。。。 每個開發者開發一個元件都會需要配置路由,會導致router檔案不易管理,容易導致衝突,甚至故障。 so。。,也許,可能可以每個元件資料夾下對於一個XXX.router 檔案,前端程式碼打包上傳到線上時觸發某個鉤子函式,將XXX.router檔案統一合併到中央router檔案中,從而避免多人操作router檔案。