queryString (查询字符串)
通常我们把 URL `?` 后面的内容称为 queryString,在 React.js 中,我们可以通过 `this.props.location.search` 来获取,它的值是字符串,
格式为:?k1=v1&k2=v2,为了方便操作,我们把它转成对象形式
URLSearchParams
在原生 JJavaScript 中内置了一个 URLSearchParams 的类,我们通过它可以很方便的操作 queryString
js原生方法或者可以用qs 库,效果同原生
https://www.npmjs.com/package/qs
安装
npm i -S qs
使用
import queryString from 'qs';
let qsTest = queryString.parse(search, {ignoreQueryPrefix: true});
let sort = qsTest.sort;
通过 JavaScript 编程的方式切换路由
除了使用 \<Link\> 组件像 a 一样点击跳转路由,我们还可以通过编程的方式(JavaScript) 来切换路由
应用场景(四)
现在,我想给页面顶部的导航加上高亮效果,用来标识当前页面。这个时候,我们就可以使用 react-router-dom 提供的 NavLink
组件来实现
NavLink 组件
NavLink 与 Link 类似,但是它提供了两个特殊属性用来处理页面导航
activeStyle
当当前 URL 与 NavLink 中的 to 匹配的时候,激活 activeStyle 中的样式
activeClassName
与 activeStyle 类似,但是激活的是 className
isActive
默认情况下,匹配的是 URL 与 to 的设置,通过 isActive 可以自定义激活逻辑,isActive 是一个函数,返回布尔值
exact
精确匹配
strict
严格模式
应用场景(五)
当用户访问不存在的路由,我们需要提供一个反馈页面,也就是 404
index.js
NotFound.js
默认情况下,React.js 会渲染所有与之匹配的路由组件,上面的案例中,当我们访问任意路由(如:/about),也会匹配 NotFound
路由组件渲染
Switch 组件
该组件只会渲染首个被匹配的组件
应用场景(六)
现在,我们要给用户增加一个购物车的功能
index.js
<NavLink to="/cart" activeStyle={{color:'red'}} exact>Cart</NavLink>Cart.js
Cart.js app.js注册登录
index.js
Redirect 组件
未登录用户是不能访问购物车的,所以,我们需要在访问购物车的时候加入用户权限验证(鉴权),如果没有登录则跳转到登录
index.jsto
设置跳转的 URL
登录代码
login({username, password}) {
return new Promise( (resolve, reject) => {
if (!username || !password) {
reject('请输入用户名和密码');
}
let user = this.state.users.find(user => user.username === username && user.password === password);
if ( !user ) {
reject('用户不存在或者密码错误');
}
this.setState({
userInfo: {
id: user.id,
username: user.username
}
});
resolve('登录成功');
} );
}
<Route path='/login' component={props => {
return <Login {...props} onLogin={this.login.bind(this)} />;
}} />
// login.js
import React from 'react';
export default class Login extends React.Component {
constructor(...props) {
super(...props);
this.login = this.login.bind(this);
this.usernameRef = React.createRef();
this.passwordRef = React.createRef();
}
login() {
let {onLogin, history: {push}} = this.props;
if (typeof onLogin === 'function') {
onLogin({
username: this.usernameRef.current.value,
password: this.passwordRef.current.value
}).then(msg=>{
alert(msg);
push('/');
}).catch(e=>alert(e));
}
}
render() {
return(
<div>
<p>
用户名:<input type="text" ref={this.usernameRef} />
</p>
<p>
密码:<input type="password" ref={this.passwordRef} />
</p>
<p>
<button onClick={this.login}>登录</button>
</p>
</div>
);
}
}
应用场景(七)
我突然发现卖东西比做码农要赚钱(主要是能生发),所以加大产品投入量,期待有一天,我的头发要宝哥多,然后推荐给
莫莫。随着产品的增多,那么多的数据就不可能一次性全部展示出来,所以我们为商品的展示添加一个分页功能
Home.js Home.js// Pagination.js
import React from 'react';
import PropTypes from 'prop-types';
import {withRouter, Link} from 'react-router-dom';
class Pagination extends React.Component {
static defaultProps = {
pages: 1,
page: 1
}
static propTypes = {
pages: PropTypes.number,
page: PropTypes.number
}
render() {
let {pages, page, history: {push}} = this.props;
// console.log(this.props);
return (
<div className="pagination">
{
(new Array(pages)).fill('').map((v, i) => {
return (
<Link
key={++i}
className={i === page ? 'active' : ''}
to={'/'+i}
>
{i}
</Link>
);
})
}
前往
<input type="text" className="goto" onKeyDown={({target:{value}})=>{
if (value !== '') {
push('/' + value);
}
}} />
页
</div>
);
}
}
export default withRouter(Pagination);
withRouter 组件
如果一个组件不是路由绑定组件,那么该组件的 props 中是没有路由相关对象的,虽然我们可以通过传参的方式传入,但是如果
结构复杂,这样做会特别的繁琐。幸好,我们可以通过 withRouter 方法来注入路由对象
网友评论