没用框架自己实现了服务端渲染,现在在数据预获取放面遇到了问题
场景
每个路由对应的页面组件,会挂载一个loadData方法(类似于next.js的getInitialProps),这样,在服务端渲染的时候,会根据路由匹配出当前页面组件,调用loadData方法,扩充store,完成数据预获取。但这个页面内如果有子组件需要独立获取自身的数据,我这样实现就有问题了,因为只能根据路由匹配出当前页面,无法匹配出其内部组件,具体场景如下:
假设有文章详情页,路由是/article/:id
,对应路由页面是<ArticleDetail/>
。
详情页内一般都会有文章评论,抽象为一个组件<CommentList/>
,且评论组件是其他页面也会用到,接收id请求评论数据。
这样<ArticleDetail/>
内嵌套了<CommentList/>
组件。
遇到的问题
<CommentList/>
不是路由内的组件,服务端根据路由无法匹配到它,所以其中的loadData方法无法被调用。也就是说评论列表的数据无法预获取,也就无法放入store。
我的思路
针对这种情况,我想了可以在它的父组件<ArticleDetail/>
的loadData方法内请求评论数据放到store,<CommentList/>
再取出来显示。也就是父组件请求子组件内的数据,子组件只负责展示。
但是感觉这种方法有缺点:
- 违背了低耦合的原则,组件内的数据交互最好是由它自己独立完成。
- 被复用的组件这样搞会很麻烦,每个用到这个组件的时候都要在其所在的路由页面的loadData方法写一个请求。本质上是还是耦合度比较高的问题
还有一种办法,就是直接为这个<CommentList/>
组件也配置路由,对应/article/:id
,这样这个路由就会对应两个组件:<ArticleDetail/>
和<CommentList/>
,也就不存在上述问题了。
- 但每用一次就要配置一次路由,有点麻烦
请问大家有什么思路指点一下吗?不胜感激
next与nuxt也并没发现有什么办法,自己找了个方法保持了组件的低耦合,就是loadData方法返回一个promise,其内部是路由页面的loadData方法与其子组件页面的loadData方法,再用Promise.all()执行,待执行完毕(无论成功失败),resolve外层promise。代码如下:
可以将这个方法做个封装:
使用时将store,以及路由页面和其所有的子组件传入即可: