React-Router 学习笔记

以下程序来自官方示例教程  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/:repoNamerepoName的具体值。

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>
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值