您的位置:首页 > Web前端 > React

React-Router 学习笔记

2017-04-08 17:53 381 查看
以下程序来自官方示例教程 react-router-tutorial

传统开发中的路由,是由服务端根据不同的用户请求地址 URL,返回不同内容的页面,而前端路由则将这些任务通过 JS 在浏览器端完成(前端路由有2种实现方式,一种是html5推出的historyapi,另一种是hash路由,就是常见的 # 号,这种方式兼容性更好)。SPA应用则是前端路由的最佳适用场景,因为它结构简单,只需更新页面部分显示内容也不必每次都从服务端获取内容。
react-router 是官方指定和维护的 React 路由库,它通过管理 URL,实现组件间切换,和状态 (state) 的变化。

首先需要安装 Node.js 和 npm 包管理工具,浏览器不能直接解析 JSX 和 ES6 语法,所以需要一个编译打包工具 这里选择 webpack,全局安装 webpack 。

webpack安装和设置见我的博客: http://blog.csdn.net/heyue_99/article/details/62888974
注意安装  react-router 4.0.0以下版本,避免发生错误(真的是坑,捣腾了很久才发现是版本问题)



index.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>My First React Router App</title>
<style>
.active{
color: blue;
}
</style>
</head>
<body>
<div id="app"></div>
<!-- 编译后的js文件 -->
<script src="./main.js"></script>
</body>
</html>


使用 ES6 的import语句代替之前的require()方法来导入模块,使用class来创建”类”(js中根本不存在类,class只是语法糖)extends用来继承React.Component,constructor(){}为构造函数方法,export
default
定义了模块对外的接口 也就是”类”App,这里定义了一个叫 APP 的根组件

Router 也是一个组件,但它不会被用来渲染任何内容:

ReactDOM.render(<Router/>, document.getElementById('app'))


下面代码中的import { Router, Route, hashHistory }是ES6导入模块的另一种用法,大括号中指定了从react-router模块里导入的变量名,变量名必须与被导入模块对外接口的名称相同。

import { Router, Route, hashHistory, IndexRoute } from 'react-router';

Router 组件 使用了hashHistory管理路由的历史,通过监听切换 URL 的 hash 变化来动态渲染组件。

这里的path=”/” 代表根路径,component={App} 意思是渲染组件 App。

Route 组件可以定义多个路由,path属性值定义了
URL 中 #号 之后的路径参数

嵌套路由(就是将Route 组件嵌套):

(1)app.js中 <Route></Route>

(2)test.js中组件内部通过this.props.children属性嵌套进子组件

这样
app.js 中 <Route path=”/about” component={About}/>和 <Route path=”/repos” component={Repos}/>就成为<Route path=”/” component={App}/>的子路由。访问http://localhost:8080,会先渲染App组件,点击About 后,会在App组件内部渲染About组件。

URL参数

/repos/:userName/:repoName
用来匹配路由路径,其中:后面的部分为参数,它的具体值可以通过路由组件的this.props.params[name]属性获取到

<h2>{ this.props.params.repoName }</h2>
这里的this.props.params.repoName是为了获取路由路径——/repos/:userName/:repoName中repoName的具体值。

IndexRoute组件:

为避免访问根路径
/ (即http://localhost:8080/#/) 时,页面没有渲染任何子组件

使用 IndexRoute
组件作为首页路由:

<IndexRoute
component={Home} />

入口文件app.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory, IndexRoute } from 'react-router';
import App from './test';
import Repos from './repos';
import About from './about';
import Repo from './repo';
import Home from './home';

ReactDOM.render((
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="/about" component={About} />
<Route path="/repos" component={Repos}>
<Route path="/repos/:userName/:repoName" component={Repo} />
</Route>
</Route>
</Router>
), document.getElementById('app'));


Link 组件 几乎等同于<a/>标签,是应用中较常用的组件

Link 组件中的to属性定义了 URL 中 #号 之后的路径参数,所以要和 Route 组件中的 path值相对应。

设置一个触发状态的样式,让用户知道当前在哪个路由下:

<Link to="/about" activeClassName="active">About</L

IndexLink组件:

在test.js中加上能切换渲染Home组件的导航链接

测试时你会发现无论点击哪个导航链接,Home 链接始终处于激活状态

因为,当子路由处于激活状态时 父路由也会被激活,而/路径可以匹配任何子路由,解决办法是使用 IndexLink 组件

<IndexLink to="/" activeClassName="active">Home</IndexLink>

组件test.js:

import React from 'react';
import { Link, IndexLink } from 'react-router';

// 定义App组件
// 增加 this.props.children 用来渲染子组件
export default class App extends React.Component {
constructor(props) {
super(props);
}

render() {
return (
<div>
<h1>React Router Tutorial</h1>
<ul role="nav">
<li><IndexLink to="/" activeClassName="active">Home</IndexLink></li>
<li><Link to="/about" activeClassName="active">About</Link></li>
<li><Link to="/repos" activeClassName="active">Repos</Link></li>
</ul>
{this.props.children}
</div>
);
}
}

组件about.js:

import React from 'react';

export default class About extends React.Component{
render(){
return(
<div>About</div>
);
}
}

组件repos.js:

import React from 'react';
import { Link } from 'react-router'

export default class Repos extends React.Component{
render(){
return(
<div>
<h2>Repos</h2>

<ul>
<li><Link to="/repos/reactjs/react-router">React Router</Link></li>
<li><Link to="/repos/facebook/react">React</Link></li>
</ul>

{this.props.children}
</div>
);
}
}


组件repo.js:

import React from 'react';

export default class Repo extends React.Component {
render() {
return (
<div>
<h2>{ this.props.params.repoName }</h2>
</div>
);
}
}


组件home.js

import React from 'react';

export default class Home extends React.Component{
render(){
return <div>Home</div>
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: