麻烦搞清楚Vuex背后的逻辑并应用它

时间:2017-05-15 16:30:03

标签: javascript vue.js vuex

我是Flux结构的新手,我正在尝试更改我的应用程序以使用它,因为它看似合乎逻辑且高效。尽管我理解逻辑,但我在现实生活中应用它时遇到了麻烦。

假设我有一个虚构的电视节目SPA,使用vue,vue-router和vuex。

系列页面是一个组件,在其中我有一个包含该节目季节的部分(每个都是SeasonPoster组件),如果选择了一个季节(点击),它会显示它的所有剧集。

我有一个模块series.js用于此页面的状态(包含从API检索的系列信息)以及相应的突变和操作。

我应该在哪里存储季节/季节剧集的逻辑?我尝试为它创建一个模块seasons.js,但似乎没必要,我已经尝试将它放在系列模块中,但它并不适合,例如:

  • 当用户点击海报时,它会调度一个提交到state.selectedSeason的动作setSeason,从API获取剧集并提交到state.selectedSeasonEpisodes并在页面上显示它们。但是,当我去另一个系列'页面,它还在那里。
  • 手动清除state.selectedSeasonEpisodes和state.selectedSeason似乎是一个"解决方法"对于我没有得到的东西。我应该把它放在那里吗?
  • 我已经尝试过'#34; selectedSeasonEpisodes"和#34; selectedSeason"在state.series内部(具有系列信息并在每次输入新的系列页面时都被清除),但是我收到了很多错误,因为当系列没有加载时它的值是"空"和属性未定义。
  • 我考虑创建一个seasonsEpisodes(复数)而不是selectedSeasonEpisodes,当用户点击季节时,它们就像一个"缓存",所以如果用户点击第1季,然后是2,那么再次1,它只会进行2次api通话。对于js应用程序,这种思想是否有效,或者它只会增加状态并使应用程序变慢?
  • 在上面的方法中,它只显示.find选择的季节剧集,但是seasonEpisodes的初始状态是未定义的,因此它也会产生错误。我应该手动将初始状态定义为空数组吗?
  • 我应该在整个网站上应用此临时缓存(仅限页面刷新),也可以将其用于state.series,缓存用户点击的所有系列文件吗?

这不是我第一次遇到逻辑/应用程序问题而且面临着"在哪里放置这个"问题,所以如果有任何人有一般的想法或资源我可以用来打开我的想法和每个文件/组件的责任,我们将非常感激!

2 个答案:

答案 0 :(得分:1)

在没有看到任何内容的情况下完全按照您所做的事情进行操作有点困难,但听起来您有点误解了vuex的目的;而不是将其视为整个应用程序的数据存储,而是将其视为当前向用户显示的状态的存储,并覆盖该存储而不是在用户的视图更改。

  

当用户点击海报时,它会调度一个提交到state.selectedSeason的动作setSeason,从API获取剧集并提交到state.selectedSeasonEpisodes并在页面上显示它们。但是,当我去另一个系列'页面,它还在那里。

更有用的方法是让vuex通过其ID存储每个季节或剧集的数据,并让组件告诉vuex它想要数据的ID。当你覆盖不同的季节时#39;数据进入相同的“选择季节”。变量,你打败了使用vuex的目的。

换句话说,您的季节的vuex商店看起来像

{
  selectedSeason: {/* season data */}
}

应该看起来像

{seasons: [
    seasonFoo: {/* season data */},
    seasonBar: {/* season data */}
]}
  

手动清除state.selectedSeasonEpisodes和state.selectedSeason似乎是一个"解决方法"对于我没有得到的东西。我应该把它放在那里吗?

对 - 那个逻辑("我在哪个季节显示?")应该在组件中;它从(大概)路线或其他组件道具获得季节ID,然后向vuex询问该特定ID的数据。 vuex商店不应该关心当前向用户显示的内容。

  

我已经尝试过'#34; selectedSeasonEpisodes"和#34; selectedSeason"在state.series内部(具有系列信息并在每次输入新的系列页面时都被清除),但是我收到了很多错误,因为当系列没有加载时它的值是"空"和属性未定义。

对于异步数据调用,在数据返回之前会有一些延迟,因此组件需要能够处理空数据(显示加载微调器或空字段。)当vuex状态时更新时,组件应自动从中获取正确的数据(因为组件绑定到vuex状态)。

  

我考虑创建一个seasonsEpisodes(复数)而不是selectedSeasonEpisodes,当用户点击季节时,它们就像一个"缓存"

Vuex是那个缓存;这就是为什么vuex存在的原因。如果组件请求vuex已有的数据,它可以立即返回;如果它请求vuex还没有的数据,vuex可以从服务器请求它。 (这是您想要将vuex商店与用户的当前视图分离的部分原因;如果vuex仅包含当前正在使用的内容并在每个请求中覆盖旧数据,您可以跳过vuex完全让每个组件直接从服务器请求数据。)

  

在上面的方法中,它只显示.find所选的季节剧集,但是seasonEpisodes的初始状态是未定义的,因此它也会产生错误。我应该手动将初始状态定义为空数组吗?

如上所述,最好以能够处理空数据或空数据的方式编写组件,因为在从服务器异步请求数据时肯定会发生这种情况。如何做到最好取决于您的具体实施;你可能初始化一个空数组,因此find不会抛出错误,或者你可以推迟尝试find直到数据到达之后。

答案 1 :(得分:0)

完全取决于您如何整理存储空间,Vue并不限制您的选择。这一点很重要,因为如果您不需要,您不需要遵循特定的计划。为您的应用创建有意义的存储空间。

可能唯一严格的事情是异步任务只能在操作中完成,而经验法则是状态数据由getter访问,并通过突变进行更改(避免直接访问,尽管您没有义务) 。

如果您要求建议:

在类似情况下,我将从API中提取的所有内容存储在存储中,以防止重复API调用。应用程序并不会因此而变慢,除非您经常执行一些疯狂的内部逻辑(您可能不会),并且用户会立即获取以前获取的信息。

此外,您可以避免“清空”。通过使用v-if检查存在并将state数组/对象定义为空数组/对象来进行错误。我在这里看不到问题。

当用户点击另一个系列链接时,您可以检查您的状态(先前获取)是否已存在此信息,如果是,则立即显示,否则显示 - 在获取数据时显示加载动画并推送到缓存阵列/对象