Vuex:直接访问商店或传递属性?

Posted

技术标签:

【中文标题】Vuex:直接访问商店或传递属性?【英文标题】:Vuex: accessing store directly or passing properties? 【发布时间】:2017-05-28 16:37:34 【问题描述】:

我正在将一个纯 Vue 应用程序迁移到 Vuex,但我不确定将数据传递给下游组件的最佳方式。 Vue 的方式是将它们作为属性传递:

<component :my-prop="myProp"/>

Vuex的方式好像是直接访问store:

computed: 
    myProp: function() 
        return this.$store.state.myProp;
    

Vuex 的方式不是更紧密地耦合视图(组件)和数据(存储)层吗?另一方面,将属性向下传递可能会有点痛苦。

在 Vuex 中访问存储数据的推荐方式是什么?

【问题讨论】:

【参考方案1】:

不确定“官方”建议,但我个人更喜欢使用属性。这样,您就可以将组件与 store 分离。例如。您的组件可以重用(在其他项目中,稍后等),并且没有商店作为依赖项。

如果商店发生变化,例如VueX 的新版本,以后的另一个最佳实践,只需要更改父组件,您的所有组件都会以相同的方式运行。

【讨论】:

但是突变呢?如果组件接收存储状态作为属性并需要对其应用突变,则该组件无论如何都必须访问全局存储。我们是否应该将整个商店(不仅仅是 store.state)传递给组件? @Charles 通过整个商店是没有意义的。此外,子组件不应该改变它的道具。如果您检查我的答案并了解概念,那么这不是问题。 组件应该如何触发组件的存储突变,例如 this.$store.dispatch('refreshSomething'),它的数据作为属性传递?那仍然将组件/存储耦合在一起,不是吗?【参考方案2】:

如问题所述,获取父级中的数据,然后将其作为props 传递可能有点痛苦。作为这种痛苦的交换,我们得到了一个更好的设计,想象一下这样的情况:一个父组件有几个子组件,它自己获取数据并将数据传递给子组件。这里我们得到了前面所说的“痛苦”,但我们得到了:当数据API发生变化时,我们可以只编辑父组件文件使其再次工作,只要父遵循接口,子不需要更改(events 和 props)在我们之前定义的它们之间。 (比较容易,如果我们让孩子自己获取数据)

总的来说,是否采用一种设计,给我们带来更多的建模、更多的代码、更多的思考,取决于考虑到项目的整个生命周期,它是否有利于团队时间>。因此,那些大型系统通常有大量的设计,因为它们需要由许多人维护,经过多年的时间。但是,如果它是一个像在我的日常工作流程中为我移动一些文件的脚本这样的一次性项目,为什么不是一些肮脏但有效的代码呢?

另外,我们讨论的子组件,接收props,渲染自己,有点像pure functions,也就是说,输入相同输出相同的东西,但重复多次。就像我们喜欢functional programming 一样,它们通常形式简单,易于维护,但需要额外的努力来设计和首先编写它们,以使它们适应这个不纯的世界。

【讨论】:

【参考方案3】:

您不需要将所有内容都保存在 vuex 商店中。你仍然可以拥有组件数据,并通过 props 将它们传递给子组件。

这是我对 redux 相同问题的另一个回答:

如果状态不需要与其他组件共享,或者在组件卸载时状态不需要保持,那么你可以将它放在组件的状态中。

你可以认为 vuex store 是前端的数据库,如果你有从 API 获取的产品数据之类的东西,那么 vuex store 是正确的地方;如果您有一个下拉组件,它将采用 isOpen 道具,那么该下拉列表的父级可以将 dropdownIsOpen 保持为组件状态。

基本上是一样的想法,你会有两种组件,容器组件和展示组件。

容器组件将直接访问 vuex 存储;展示组件不需要了解任何关于 vuex 的知识,它们只接收道具,因此可以轻松重用。

【讨论】:

我认为 Charles 是在询问一个案例,即您在商店中有类似产品的东西,并且该组件是该产品的表单编辑器。产品应该通过属性传入,还是应该直接从子组件中的商店获取。 这些问题背后的概念是一样的。如何在组件状态和全局存储之间进行选择。它还将涉及基于组件的系统的设计 在产品案例中,表单编辑器是一个容器(智能)组件,因此它可以直接访问和修改存储数据。通过道具传递商店没有意义。

以上是关于Vuex:直接访问商店或传递属性?的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Vuex [Quasar] 访问商店

如何循环遍历传递给具有 Vuex 存储和计算属性的组件的对象数组?

vuex

TypeError:无法读取未定义商店调度 vuex 的属性“令牌”

使用 Vue + Vuex 在渲染之前无法获取对象的状态属性

从承诺解决方案调用时,Vuex 商店未更新