vue spa应用中的路由缓存问题与解决方案(2)

componentDidMount() { const {app: {dataSoruce = [], scrollTop}, loadData} = this.props; if (dataSoruce.length) { //判断redux中是否已经有数据源 // 有数据则不再加载收据,只恢复滚动状态 window.scrollTo(0, scrollTop); } else { //没有数据就去请求数据源 this.props.loadData(); // 在redux中定义的数据请求的action } } handleClik = () => { 在点击进入下一级页面前先保存当前的滚动距离 const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const {saveScrollTop} = this.props; saveScrollTop(scrollTop); }

首先我们可以在redux中为页面定义异步的action,将请求回来的数据放入集中的store中(redux的该相关具体用法不在细述)。在sotre里我们可以保存当前页面的数据源、滚动条高度以及其他一些可能要用到的分页数据等来帮助我们恢复状态。

在componentDidMount生命周期里,首先根据redux里store中的对应的字段,判断是否已经加载过数据源。如果已经缓存过数据则不再去请求数据源,只去恢复一下store里的存储过的一些滚动条位置信息等。如果还未请求过数据,就使用在redux中定义的异步action去请求数据,在将数据在reducer里将数据存到store中。 在render函数里,我们只需要读取redux里存储的数据即可。

为了保留要缓存页面的一些状态信息,如滚动条、分页、操作状态,我们可以在进行对应操作时候将这些信息存入redux的store中,这样当我们恢复页面时,就可以将这些对应状态一一读取并还原。

2. 使用display的属性来切换显示隐藏路由组件

想要display的属性来切换显示隐藏路由组件,首先要保证路由组件不会在url变化时候被卸载。在react-router中最使用的Route组件,它可以通过我们定义的path属性来与页面路径来进行匹配,并渲染对应的组件,从而达到保持UI与URL同步变化的效果。

首先简要看下Route组件的实现 GitHub Route.js

return ( <RouterContext.Provider value={props}> {children && !isEmptyChildren(children) ? children : props.match // props.match 属性来确定是否要渲染组件 ? component ? React.createElement(component, props) : render ? render(props) : null : null} </RouterContext.Provider> );

上述代码出现在关键的render方法最后的return中

Route组件会根据props对象中的match属性来确定是否要渲染组件,如果match匹配到了就使用Route组件上传递的component或者render属性来渲染对应组件,否则就返回null。

然后溯源而上,我们找到了props对象中关于match的定义:

const location = this.props.location || context.location; const match = this.props.computedMatch ? this.props.computedMatch // <Switch> already computed the match for us : this.props.path ? matchPath(location.pathname, this.props) : context.match; const props = { ...context, location, match };

上述代码显示,match首先会从组件的this.props中的computedMatch属性来判断:如果this.props中存在computedMatch则直接使用定义好的computedMatch属性赋值给match,否则如果this.props.path存在,就会使用matchPath方法来根据当前的location.pathname来判断是否匹配。

然而在react router的Route组件API文档中我们似乎没有看到过有关于computedMatch的介绍,不过在源码中有一行这样的注释

// <Switch> already computed the match for us

该注释说在<Switch>组件中已经为我们计算了该匹配。

接下来我们再去了解一下Switch组件

Switch组件只会渲染第一个被location匹配到的并且作为子元素的<Route>或者<Redirect>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/9fd02ebfacd2128b99fa263f7bf8bd48.html