react学习第三天笔记
2018-12-29 本文已影响0人
果木山
react路由
模块
- 下载
react-router模块,版本3.0.5; - 解构赋值:Router,Route,hashHistory;如:
import {Router,Route,hashHistory} from "react-router";
简单路由
- 通过Router包裹Route标签;地址栏中通过
http://localhost:8080/#/app;渲染app页面;
import React,{Component} from "react";
import ReactDom,{render} from "react-dom";
import {Router,Route,hashHistory} from "react-router";
//Router:整体路由;
//Route:单个路由;
import App from "./component/App";
import Contact from "./component/Contact";
class Index extends Component{
render(){
return(
<Router history={hashHistory}>
<Route path="/app" component={App}>
<Route path="/contact" component={Contact}/>
</Router>
)
}
}
render(<Index/>,document.getElementById("app"));
路由嵌套
- 在Route标签中继续嵌套Route标签;
class Index extends Component{
render(){
return(
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="contact" component={Contact}/>
<Route path="about" component={About}/>
</Route>
</Router>
)
}
}
导航菜单的跳转
- react-router中结构赋值出Link和IndexLink;如
import {Link,IndexLink} from "react-router"; - 代码:
<Link to="/"></Link>和<IndexLink to="/shou">xx</IndexLink>
路由的激活效果状态
- activeStyle 行内样式;
- 模板:
activeStyle={{color:"red",fontSize:"20px"}} - 注意:内容使用双花括号;
- 模板:
- activeClassName 非行间样式;引入外界的css文件,然后设置class名;如:
activeClassName="current";
IndexLink
- 一般情况下,当我们访问"/about"的时候,会默认激活两个路由;
- "/"对应的组件;
- "about"对应的组件;
- 如果使用了IndexLink,就可以只激活我们要找的那个路由;
导航栏小实例
- 知识点
- this.props.children在点击每个li标签后,才能获取,并显示,如果,不跳转,则拿到的children为null,点击哪个li标签,拿到的children就为哪个标签;
- 正常点击情况下,会访问两个组件,一个是"/"对应的组件,一个是"about"对应的组件;
- Link和IndexLink的区别;
- 行间样式activeStyle和非行间样式activeClassName的设置;
- this.props.children的获取值;
- 代码:
- index.js代码
import React,{Component} from "react"; import ReactDom,{render} from "react-dom"; import {Router,Route,hashHistory} from "react-router"; //Router:整体路由; //Route:单个路由; import App from "./component/App"; import Contact from "./component/Contact"; import About from "./component/About"; class Index extends Component{ render(){ return( <Router history={hashHistory}> <Route path="/" component={App}> <Route path="contact" component={Contact}/> <Route path="about" component={About}/> </Route> </Router> ) } } render(<Index/>,document.getElementById("app"));- App.js代码
import React,{Component} from "react"; import {Link,IndexLink} from "react-router"; import "./index.css"; class App extends Component{ render(){ const style={ color:"blue", fontSize:"30px" }; return( <div> <h1>这是导航菜单</h1> <ul> <li> <IndexLink to="/" activeClassName="current">这是首页</IndexLink> </li> <li> <Link to="/contact" activeStyle={{color:"red",fontSize:"20px"}}>这是Contact</Link> </li> <li> <Link to="/about" activeStyle={style}>这是关系我们</Link> </li> </ul> {/*点击谁,拿到的children就为哪个标签*/} {this.props.children} </div> ) } } export default App;
路由参数
- 通过在Route标签设置path属性,通过":"来设置;在子组件About中通过"this.props.params.xx"获取;
- 代码:
<Route path="/about/:a/:b" component={About}/>; - index.js代码:
class Index extends Component{ render(){ return( <Router history={hashHistory}> <Route path="/" component={App}> <Route path="contact" component={Contact}/> <Route path="about/:a" component={About}/> </Route> </Router> ) } }- About.js代码:
class About extends Component{ render(){ return( <div> <h2>关于我们 {this.props.params.a}</h2> </div> ) } } - 代码:
重定向
- 通过react-router中的属性Redirect;解构赋值出来;
- 代码:
<Redirect from="about" to="about/react111"></Redirect> - from:指用户输入的地址; to:指的是跳转到哪里;
- 代码:
打印的this.props的参数
- 如下代码中,在index.js中设置Route路由,跳转About.js文件,在About.js中打印this.props后得到的是一个对象;对象中有多个属性:
- children:
- location:解析地址栏
- params
- route
- router:属性值为对象,对象中存在goBack,goforward等属性,对应属性值为函数,注意:调用函数时必须保证this为实例;
- 调用goBack()函数:
<button onClick={()=>{this.props.router.goBack()}}>go Back</button> - 回退功能也可以使用
browserHistory.goBack()
- 调用goBack()函数:
默认路由
- react-router中的属性IndexRoute,即默认打开的页面;
- 解构赋值:
import {IndexRoute} from "react-router"; - 当跳转"/"时,会默认显示两个组件,App和Home组件;
- 代码:
class Index extends Component{ render(){ return( <Router history={hashHistory}> <Route path="/" component={App}> <IndexRoute component={Home}/> <Route path="contact" component={Contact}/> <Route path="about/:a" component={About}/> <Redirect from="about" to="about/react111"/> </Route> </Router> ) } } - 解构赋值:
history
- history属性类型
- 解构赋值react-router;如:
import {hashHistory,browserHistory} from "react-router" - hashHistory:在地址栏中会存在"#",如
http://localhost:8080/#/contact- 不需要你配置服务器即可使用
- 不支持服务端渲染
- 不建议在生产环境使用
- browserHistory:在地址栏中不会存在"#",如:
http://localhost:8080/contact- 需要配置路由器:在package.json文件中的"script"下的"start",后面添加
--history-api-fallback
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server --progress --colors --content-base dist --history-api-fallback", "build": "webpack --progress --colors" }- 通过URL变化来改变路由的,调用的是浏览器的History
- 一般用于线上生产环境
- 需要配置路由器:在package.json文件中的"script"下的"start",后面添加
- 解构赋值react-router;如:
路由跳转
- Link:利用to来跳转地址,进而打开对应的模块;如:
<Link to="/">...</Link> - browserHistory.push():路由跳转
- 需要拼接地址
- 如果是表单的情况下,我们需要对表单中的form添加一个onSubmit事件
- 事件中需要通过
e.preventDefault(),阻止表单默认提交的事件; - 通过e.target.elements来获取表单下对应的子节点;
- 需要检查路由,因为拼接的路由形式为:
/about/xxx/xxx,所以,如果拿到参数,必须把路由设置为/about/:xx/:xx; - 在路由对应的模块中,通过
this.props.params.xx来获取对应的参数;
- 代码:
- index.js中路由设置代码:
lass Index extends Component{ render(){ return( <Router history={browserHistory}> <Route path="/" component={App}> <IndexRoute component={Home}/> <Route path="contact" component={Contact}/> <Route path="/about/:a/:b" component={About}/> {/*重定向*/} <Redirect from="about" to="about/react111/d"/> </Route> </Router> ) } }- App.js代码:
import React,{Component} from "react"; import {Link,IndexLink,browserHistory} from "react-router"; import "./index.css"; class App extends Component{ data=(e)=>{ e.preventDefault(); //e.target拿到的是form标签,e.target.elements拿到的是所有的表单标签 var username=e.target.elements[0].value; var info=e.target.elements[1].value; //拼接地址 var path=`/about/${username}/${info}`; //利用browserHistory.push(),设置路由 browserHistory.push(path); }; render(){ return( <div> <h1>这是导航菜单</h1> <ul> <li> <form onSubmit={this.data}> <p> 用户名: <input type="text" name="username"/> </p> <p> 用户名信息: <input type="text" name="info"/> </p> <p> <input type="submit" value="提交参数"/> </p> </form> </li> </ul> {/*点击谁,拿到的children就为哪个标签*/} {this.props.children} </div> ) } } export default App;
- 需要拼接地址
- this.context.router.push():路由跳转
- 与browserHistory.push()用法相同,就是所用的代码不同;
data=(e)=>{ e.preventDefault(); var username=e.target.elements[0].value; var info=e.target.elements[1].value; //拼接地址 var path=`/about/${username}/${info}`; //利用this.context.router.push()设置路由跳转 this.context.router.push(path); };- 注意:使用context必须设置contextTypes,否则,拿到的this.context为空对象;
//下载并prop-types模块 import PropTypes from "prop-types" //使用context必须设置contextTypes,否则,拿到的为空对象;App为组件名; App.contextTypes={ router:PropTypes.object };
setRouteLeaveHook
- 离开组件的时候执行的函数;
- 代码:
this.context.router.setRouteLeaveHook(this.props.route,this.LeaveHook) - 指的是在离开某个组件,跳转到别的路由时,所调用的函数;
- 在componentDidMount函数中使用该代码,指的是在渲染页面完成后,就设置setRouteLeaveHook,当离开时,就会执行函数;
import React,{Component} from "react"; import PropTypes from "prop-types"; class Contact extends Component{ //当渲染页面完成后,执行函数 componentDidMount(){ this.context.router.setRouteLeaveHook(this.props.route,this.LeaveHook); } LeaveHook=()=>{ alert("离开该组件") }; render(){ return( <div> <h5>联系我们</h5> <button onClick={()=>{this.props.router.goBack()}}>go Back</button> </div> ) } } Contact.contextTypes={ router:PropTypes.object }; export default Contact; - 代码: