React为 Vue 引入容器组件和展示组件的教程详解(3)
使用 @xunlei/vuex-connector 实现容器组件
上面演示的容器组件的代码非常简单,实际上如果直接投入生产环境,会产生一些问题。
手动实现容器组件存在的不足
代码比较繁琐
在上面的例子中,每次传递一个 state 都要定义一个 computed,每传递一个 mutation 或者 action 都需要定一个方法,而且还要注意这个方法的参数要透传过去,同时还要处理返回值,比如异步的 action 需要返回 promise 的时候,定义的这个 method 也得把 action 的返回值返回出去。
无法透传其他 props 给展示组件
比如展示组件新增了一个 prop 叫做 type,可以传递一个评论的类型,用来区分是热门还是最新,如果用上面的容器实现方式,首先需要在容器组件这层新增一个 prop 叫做 type 接受外部传来的参数,然后在展示组件内部同样定义一个 叫做 type 的 prop,然后才能传递下去。
需要透传的 prop 必须定义两遍,增加了维护的成本。
<CommentListContainer type="热门"></CommentListContainer> <CommentList :fetch="fetchComments" :comments="comments" :type="type" ></CommentList>
容器组件无法统一进行优化
每一个手动实现的容器组件实质上代码逻辑非常近似,但是没有经过同一层封装,如果目前实现的容器组件存在一些性能优化的地方,需要每个容器组件都进行统一的修改。
无法控制展示组件不去获取 store
因为容器组件是通过 this.$store 获取 store 的,展示组件内部实质上也可以直接跟 store 通信,如果没有约束,很难统一要求展示组件不得直接和 store 通信。
使用 @xunlei/vuex-connector
@xunlei/vuex-connector 借鉴了 react redux 的 connect 方法,在 vuex 基础上进行的开发。
有以下几个特点:
代码非常简洁
下面是上面例子中手动实现的容器组件的改造版本:
comonents/ConnectCommentListContainer.vue
<script> import CommentListNew from '@/components/CommentListNew' import { connector } from '@/store' export default connector.connect({ mapStateToProps: { comments: (state) => state.comments }, mapActionToProps: { fetch: 'fetchComments' } })(CommentListNew) </script>
通过 connector 的 connnect 方法,传入要映射的配置,支持 mapStateToProps, mapGettersToProps, mapDispatchToProps, mapCommitToProps 这四种,每一种都是只要配置一个简单的 map 函数,或者字符串即可。