React-router新手入门
关于react-router的解释。
声明:本人也是一个新手,此篇文章只是作为一个参考,纯粹给大家作为一种借鉴参考,若有错误,可评论指出,谢谢。
此文参考前端先生的文章!
首先:
在使用react-router的时候截止目前应该使用router3.0以上的版本,推荐目前使用3.0因为3.0和之前的2.0改动较小,而4.0据说改动很大。如果使用2.0版本,虽然能够运行,但是控制台会报错,要求你更换最新的版本。
安装:
在安装的时候使用指定版本号,如:npm install [email protected] --save
使用:
因为router也是一个组件,所以要和自己定义组件那样去调用它。
基础的调用如下:
import { Router,Route,hashHistory} from 'react-router'
Router:
这是最外层的容器,类似于标签,而正真实现路由的需要依靠Route.
而这个容器(Router)有一个参数history.这个参数的作用是指定我们路由的方式。
它一共有三种方式:
browserHistory
hashHistory
createMemoryHistory
第一种方式:
browserHistory这是官方推荐的路由方式,使用之后浏览器的地址是这样的(/user/liuna),但是这种方式需要服务端的支持。所以,如果是静态页面不需要使用这种方式。
第二种方式:
hashHistory这种方式相比较第一种,他不需要服务端的支持,在做静态页面的时候,可以使用这种方式,使用之后浏览器的地址是这样的(/#/user/liuna?_k=adseis)
第三种方式:
createMemoryHistory这种方式。其实react-router中history是依赖于history这个第三方JS库的,而createMemoryHistory是在node环境中运行。详细可以查看http://www.tuicool.com/articles/eUBvIjj中的解释。
综合上述三种方式,我们在开发中只需要选择第一和第二两种,对于平时做做测试可以选择第二种,而如果正真做项目还是用官方推荐的browserHistory这种方式吧。
Route:
这是路由的关键部分。
基本使用:
注:以下内容是基于我们已经会书写组件的基础上,而只缺少单页面之间的跳转!
使用一:
这是我们路由基本的使用方式。首先在render方法中使用一组Router然后为它指定我们的路由方式,这里我使用hashHistory。然后我们在其中书写我们要展示的组件(因为这里的组件是我们完成拼接的完整页面,所以也可以理解为展示页面)。这里的Path表示的是路径,component表示的是我们需要渲染的组件,以上是一个组件路由的最基础的方式。
使用二:
在我们日常开发中会有多张页面,这个时候我们就需要使用path来为他们设置专门的路径。下面我为大家展示出新增两个组件。
上图中,我们可以看出一共引入了三个组件,包括一开始的App组件和之后新增的Test1和Test2。他们分别都有各自的path路径。这里需要注意的是,path=”/”这是表示默认显示的首个组件(也就是页面),如果有两个都是”/”,那么它将会显示第一个path=”/”的组件。
使用三(Link组件的使用):
以上的例子介绍了为组件指定一个特定的路径。那么在日常项目中,我们常常会有以下需求:我们的首页中有一个按钮,当我们点击这个按钮的时候我们需要它跳转到对应的组件(页面)中。
上图中,我们首先导入了router中的Link组件,它的作用和a标签相同。而这里的to需要和我们在主入口文件中的路径相同。
这里要和大家说明一定,route中是可以嵌套别的路由。下面就介绍了一下路由的嵌套。
使用四(组件间的嵌套):
在日常移动端项目中我们可能经常会使用到路由嵌套,也许新手的大家可能没注意,我先上一张图。
这是微信的UI界面,整个界面,我们可以视为我们的App组件,组件内有4个,他们分别对应4个不同的组件,当我们点击其中一个按钮,就会跳转到对应的组件,将其渲染到我们内容区域,同时其底部的界面不变化,下面为大家展示一下。
界面上是有点丑,不过这里我只是展现一下效果。
下面我将这个案例的源码贴出来。
在主入口文件index.js中将需要路由的4个组件全部放入App组件路由内,这样其中4个组件就会渲染在App组件内,而不会将App组件的内容刷新掉。
而在App组件中则是要添加{this.props.children}。这里需要注意的是,{this.props.children}不能写在最外层 使用五(多层组件的嵌套): 三层以上的嵌套其实和二层一样,这里我将一个案例贴出来,大家可是自己试着敲一下。 这里需要注意的是,其他的组件都需要添加{this.props.children}这样才能将子组件渲染出来。 使用六(Link组件触发状态): 在日常开发中,我们的导航栏经常需要体现用户,当前点击的是那一栏,改变他的状态使得用户能够知道自己当前所点击的是哪里。 在使用Link组件的时候,可以添加activeStyle={{属性:值}},从而改变当前点击的状态。 这第一张做法,当然也有第二种做法就是添加activeClassName=”样式名”,这种做法等同于外部引入css样式。 思考:在我们的项目中一般来说,只有个别地方使用点击之后触发状态的效果,所以为了方便,我们可以将Link组件再次进行封装。
以上就是将Link组件在此封装成NavLink组件,这样在之后我们就能像自己定义的组件那样去调用它。 值得注意的是,在封装Link组件的时候我们需要传入{...this.props}这是ES6中的语法。 使用七(URL参数的使用): 在使用路由的时候,我们可以在URL中传入参数,从而去做一些我们想要的事情。而且可以通过特定的一个方式将我们传入URL中的参数展现在我们的页面中或者使用这个传入的参数。 路由中在App组件内包含两个子组件,分别是boys和boy。 App组件内有一个Link,他指向我们Boys组件。 而在我们Boys组件中这是两个跳转到boy组件的Link。 在最后Boy组件中则是通过{this.props.params.boyName}的方式将我们Route中”/boy/:boyName”内的boyName的值显示在我们h2标签内。 综上所述,我们可以通过this.props.params.(路由中自己定义的值),拿到URL中的参数。 看起来有点乱。我们来总结一下流程:首先我们需要在路由组件中为path指定URL路径,并且通过“:参数名”的形式指定参数名。而这里的参数名我们可以通过this.props.params.参数名的形式将其获得。而在Link 跳转组件中,我们可以通过to=”路径/具体的参数”。这样当我们点击Link链接的时候,子组件就会获得to=”路径/具体的参数”中那个具体参数。 大家可以动手操作一下,感受一下。 使用八(IndexRoute组件): 在上面案例中,对于组件的嵌套,我们应该发现了一个问题,那就是一个组件中有多个子组件的时候,我们初始加载的时候,并不知道先渲染那个组件。这样就会出现两个子组件都不被渲染出来。 第一种做法: 使用这种方式,能够让页面在一开始渲染时,因为都没有点击子组件,所以首先渲染出Home组件的内容。但是这种方式并不优雅,最优的方式就是在路由阶段就声明如果子组件还没被渲染,首先渲染什么组件。这时候我们就需要使用IndexRoute这个组件了。 如上图,我们在使用IndexRoute的时候,首先需要将这个组件引入,另外将我们自己Home组件也一并引入。最后在路由中我们使用IndexRoute 将Home组件引入。需要知道的是,IndexRoute没有path这个属性。 使用九(IndexLink组件): 上面的案例中,大家会发现一个问题,虽然我们调用了一个Home组件进去防止一开始渲染没有子组件被点击而产生页面空白的问题,但是我们还是多了另一个问题,那就是Home我们希望他能在点击子组件之后还能再次被点击渲染出来。 简单的方式是,在App组件中添加一个Home组件的Link。 因为这是要回到主路径中,所以这里路径设置了”/”。 如此设置,我们依然发现了一个问题。那就是当我们点击其他组件的时候,Home组件一直处于被点击的状态。网上有人说明了原因:当子路由处于激活状态时,父路由也会被激活,而 / 路径可以匹配任何子路由。 这样,问题就应该解决了。当然,也可以不使用IndexLink组件,使用单纯的Link组件解决这个问题。 先上图: 只需要在Link组件中加入onlyActiveOnIndex={true},也可以解决这个问题。查阅资料,其实IndexLink就是Link和onlyActiveOnIndex={true}组合起来的组件。所以两种方式都可以。 其他位置内会是怎样的。