react 的环境搭建(新)(2018/12/15)
一、react环境的搭建
1 全局安装(react 脚手架的安装):cnpm install create-react-app -g
2 局部安装(在文件路径下):create-react-app 项目名称 //相当于创建了一个myrouter的文件夹
3 cd myrouter 进去myrouter 文件夹
4 npm start 会自动开启项目的网页
package.json
"scripts": {
"start": "react-scripts start", //启动项目
"build": "react-scripts build", //打包项目
"test": "react-scripts test", //测试项目
"eject": "react-scripts eject" //暴露webpack的配置文件,一但暴露出去就不能更改
},
单页面开发 是根据用户请求页面数据的不同去重新渲染页面
二、react路由的安装和使用
(1)在myrouter文件路径下进去cmd------>yarn add react-router-dom --dev(安装路由插件)
(2)在需要使用路由的组件内部引入路由--------> import {HashRouter as Router,Route,Link,NavLink} from "react-router-dom"
所有的路由配置都需要在当前组件内部
BrowserRouter:路由的一种形式 不带hash值的路由 需要配置后端服务器进行使用,在工作中用这个
HashRouter:带hash值的路由
Router下面只允许有一个子元素,凡是被Router包裹的组件,这个组件内部都能进行路由的嵌套
渲染相对应的组件
Route:
属性:
path------匹配的路径 // 当path匹配成功的时候会渲染component/render中的组件
component------渲染的方式(与render二选一使用)
render------渲染的方式
路由跳转的方式
Link:
属性:
to ----- 决定跳转到哪个路由路径
<a href="#/路径"></a> :
属性:
href
NavLink
属性:
to ----- 决定跳转到哪个路由路径
区别:
NavLink被选中的时候会加一个active类名,通过这个类名可以设置css样式,多用于导航栏
重定向方式
Redirect --------- <Redirect path="/" to="/需要直接跳转的路径" />
App.js
import React, { Component } from 'react';
//import {BrowserRouter,Route,Link} from "react-router-dom" //Route 和 Link 是路由的配置项
import {HashRouter as Router,Route,Link,NavLink,Redirect} from "react-router-dom" //这样写就可以用<Router>标签代替<HashRouter>标签
import Home from './components/home' //这里是引入组件
import List from './components/list'
import My from './components/my'
class App extends Component {
render() {
return (
/* <BrowserRouter> //因为browserRouter需要配合后端使用,所以这里不用它
<Route path="/home" component={Home}/> //Route 用来匹配路径渲染组件
</BrowserRouter>*/
<Router> //这里的Router是HashRouter转换的
<div>
<Route path="/home" component={Home} />
<Route path="/list" component={List}/>
<Route path="/my" component={My}/>
<Redirect path="/" to="/home" /> //重定向,一定要写在最后,当路径为xxx时 跳转到xxx路径
<div id="footer">
<ul>
<li><NavLink to="/home">首页</NavLink></li> //这是NavLink跳转路由
<li><NavLink to="/list">详情</NavLink></li>
<li><NavLink to="/my">我的</NavLink></li>
</ul>
</div>
{/* <Link to="/home">首页</Link> //这是Link的方式跳转路由
<Link to="/list">详情</Link>
<Link to="/my">我的</Link> */}
{/* <a href="#/home">首页</a> //这是a标签的方式跳转路由
<a href="#/list">详情</a>
<a href="#/my">我的</a> */}
</div>
</Router>
);
}
}
export default App;
home.js (通过路由跳转进行显示)
import React,{Component} from 'react'
class Home extends Component{
render(){
return(
<div>Home</div>
)
}
}
export default Home
三、二级路由的跳转
Switch: 只会匹配一个路由的路径
exact:要求路径完全匹配成功 to和path的值必须完全匹配
import React, { Component } from 'react';
import {HashRouter as Router,Route,Link,NavLink,Switch} from "react-router-dom" //这样写就可以用<Router>标签代替<HashRouter>标签
import Home from './components/home'
import HomeOne from './components/homeOne' //这是home组件下的二级路由
class App extends Component {
render() {
return (
<div>
<Switch> //表示一次只能匹配一个路由路径
<Route path="/home" exact component={Home} /> //由于路径是从上到下匹配的 /home/homeOne先匹配到了/home路径 所以会显示/home中的内容,为了避免这种情况需要加一个exact 进行绝对匹配 路径完全一样才可以匹配到
<Route path="/home/homeOne" component={HomeOne}/>
</Switch>
<div id="footer">
<ul>
<li><NavLink to="/home">首页</NavLink></li>
</ul>
</div>
</div>
</Router>
);
}
}
export default App;
home.js
import React,{Component} from 'react'
import {Link} from 'react-router-dom' //因为只用到Link这个配置项所以 引入Link就行
class Home extends Component{
render(){
return(
<div>
<p>这是home页面</p>
<Link to="/home/homeOne">跳转二级页面homeOne的路由</Link> //在home页面设置二级页面的跳转按钮
</div>
)
}
}
export default Home
homeOne.js(二级路由)
import React,{Component} from 'react'
class HomeOne extends Component{
render(){
return (
<div>这是HomeOne</div>
)
}
}
export default HomeOne
四、编程式导航
在constructor中 console.log(this.props)
this.props.history.push 跳转
this.props.history.goBack 返回
this.props.history.goForward 前进
this.props.history.replace 清除掉路由跳转的历史记录
home.js
import React,{Component} from 'react'
import {Link} from 'react-router-dom'
class Home extends Component{
constructor(props){ //编程式导航的路由跳转需要接受props的值
super(props)
this.state={
}
console.log(this.props) //这里会有 history 属性,他身上有 push goBack goForward等方法
}
render(){
return(
<div>
<p>这是home页面</p>
{/*<Link to="/home/homeOne">跳转二级页面homeOne的路由</Link>*/}
<button onClick={this.handleTo.bind(this)}>跳转到二级页面HomeOne</button>
<button onClick={this.handleForward.bind(this)}>前进</button>
</div>
)
}
handleTo(){
this.props.history.push("/home/homeOne") //这里是push方法
}
handleForward(){
this.props.history.goForward() //括号里不写路径,自动返回上一个页面
}
}
export default Home
homeOne.js
import React,{Component} from 'react'
class HomeOne extends Component{
render(){
return (
<div>这是HomeOne
<button onClick={this.handleBack.bind(this)}>返回</button>
<button onClick={this.handleReplace.bind(this)}>替换</button>
</div>
)
}
handleBack(){
this.props.history.goBack("/home") //this.props只有在被router包裹的组件中才能被获取到
}
handleReplace(){
this.props.history.replace("/home") //可以指定要跳转的页面但是不会保留跳转的历史记录,也就是不能返回上一个页面
}
}
export default HomeOne
五、比较component 与 render 渲染方式的不同
(1) component渲染的时候值是一个组件名称
render渲染的时候值是一个函数,需要返回一个组件/标签
(2) component渲染的时候不能进行组件的传值
render渲染的时候可以进行组件传值
(3) component渲染组件的时候可以直接通过this.props拿到history macth location
render渲染的时候需要手动的在函数中解构需要用到的参数 通过组件传值的方式进行传递
App.js
<Switch>
{/* <Route path="/home" exact component={Home} /> //这是component渲染的方法
<Route path="/list" component={List}/>
<Route path="/my" component={My}/>
<Route path="/home/homeOne" component={HomeOne}/>
<Redirect path="/" to="/home" />*/}
{/* <Route path="/home" exact render={(props)=>{ //这是render渲染的方法
return <Home val="123"/> //组件传值给/home页面
}}/>*/}
<Route path="/home" exact render={({history,location,match})=>{ //手动的在函数中解构需要用到的参数 通过组件传值的方式进行传递
return <Home history={history} location={location}/>
}}/>
<Route path="/my" exact render={()=>{
return <My/>
}}/>
<Route path="/home/homeOne" exact render={()=>{
return <HomeOne/>
}}/>
<Route path="/" exact render={()=>{ //重定向在render渲染时的写法
return <Redirect to="/home"/>
}}/>
</Switch>
home.js
import React,{Component} from 'react'
class Home extends Component{
constructor(props){
super(props);
console.log(this.props) //{val:{123}}
}
render(){
return(
<div>
<h2>{this.props.val}</h2> //通过this.props接收到App.js传过来de值 渲染到页面上
</div>
)
}
}
export default Home
六、 路由的传参
1、path路径传值(params)
params传值的参数是存在 this.props.match.params中的
home.js
import React,{Component} from 'react'
import {Link} from 'react-router-dom'
class Home extends Component{
constructor(props){
super(props);
this.state={
goodList:["苹果","香蕉","橘子"]
}
}
render(){
let {goodList} = this.state
return(
<div>
<p>这是home页面</p>
{
goodList.map((item,index)=>{
return <li key={index}><Link to={"/detail/"+index+"/"+item}>{item}</Link></li> //Route中的值是key,link中的是value 通过路径传参给detail页面
})
}
</div>
)
}
}
export default Home
在detail.js中console.log(this.props)
detail.js
import React,{Component} from "react"
class Detail extends Component{
constructor(props){ //这是获取home.js中传过来的值
super(props);
this.state={
id:"",
name:""
}
console.log(this.props)
this.state.id = this.props.match.params.id //给this.state中的属性赋值
this.state.name = this.props.match.params.name
}
render(){
let {id,name} = this.state
return(
<div>
<p>商品的编号为----{id} 商品的名称为---{name}</p> //渲染数据到页面上
</div>
)
}
}
export default Detail
App.js
import Details from "./components/detail"; //引入文件
<Route path="/detail/:id/:name" component={Detail}/> //渲染相对应的组件
2、query传值
query传值的参数是存在 this.props.location.search中的
home.js
import React,{Component} from 'react'
import {Link} from 'react-router-dom'
class Home extends Component{
constructor(props){
super(props);
this.state={
goodList:["苹果","香蕉","橘子"]
}
}
render(){
let {goodList} = this.state
return(
<div>
{
goodList.map((item,index)=>{
return <li key={index}><Link to={"/detail?id="+index+"&name="+item}>{item}</Link></li>
})
}
</div>
)
}
}
在detai.js中console.log(this.props)和 console.log(data)
detail.js
import React,{Component} from "react"
const qs = require("querystring")
class Detail extends Component{
constructor(props){
super(props)
this.state={
id:'',
name:''
}
console.log(this.props)
let data = qs.parse(this.props.location.search.slice(1)) //parse的作用是将字符串传化为对象形式,slice(1)是去掉?
console.log(data)
this.state.id = data.id
this.state.name = data.name
}
render(){
let {id,name} = this.state
return(
<div>
<p>商品的编号是----{id} 商品de名称是----{name}</p>
</div>
)
}
}
export default Detail
3、编程式导航传值 (传过来的值在页面刷新之后就没有了,解决办法是将传递过来的值保存在localstorage中)
传过来的值保存在this.props.history.location 和 this.props.location中
home.js
import React,{Component} from 'react'
class Home extends Component{
constructor(props){
super(props);
this.state={
goodList:["苹果","香蕉","橘子"]
}
console.log(this.props)
}
render(){
let {goodList} = this.state
return(
<div>
<p>这是home页面</p>
{
goodList.map((item,index)=>{
return <li key={index} onClick={this.handleData.bind(this,index,item)}>{item}</li>
})
}
</div>
)
}
handleData(index,item){ //传递下标和item的值
console.log(this.props)
this.props.history.push({ //这是跳转的路径
pathname:"/detail",
state:{
id:index,
name:item
}
})
}
}
export default Home
在detail中console.log(this.props)
detail.js
import React,{Component} from "react"
class Detail extends Component{
constructor(props){
super(props)
this.state={
id:'',
name:''
}
console.log(this.props)
let data = this.props.location.state //this.props.history.location.state 也可以,因为 this.props中的history里有location属性,this.props中也有location属性
this.state.id= data.id
this.state.name = data.name
}
render(){
let {id,name} = this.state
return(
<div>
<p>商品的编号是----{id} 商品de名称是----{name}</p>
</div>
)
}
}
export default Detail
4、对象传值 (与编程式导航传值差不多,只是这个直接写在Link里)
home.js
{
goodList.map((item,index)=>{
return <li key={index}><Link to={{pathname:"/detail",state:{id:index,name:item}}}>{item}</Link></li>
})
}

浙公网安备 33010602011771号