无法弄清楚 Vuex 背后的逻辑并应用它

Trouble figuring out the logic behind Vuex and applying it

我是 Flux 结构的新手,我正在尝试更改我的应用程序以使用它,因为它看起来合乎逻辑且高效。就我所理解的逻辑而言,我在现实生活中很难应用它。

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

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

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

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

这不是我第一次遇到 logic/application 问题并面临 "where to put this" 问题,所以如果有人有一般的想法或资源,我可以用来打开我的想法和责任每个 file/component,我们将不胜感激!

在看不到任何东西的情况下,很难准确地理解你在做什么,但听起来你有点误解了 vuex 的目的;您不是将其视为整个应用程序的数据存储,而是将其视为当前显示给用户的状态的存储,并在用户视图更改时覆盖该存储而不是扩展它。

When the user clicks a poster, it dispatches an action setSeason that commits to state.selectedSeason, get the episodes from the API and commit to state.selectedSeasonEpisodes and shows them on the page. But, when I go to another series' page, it's still there.

一个更有用的方法是让 vuex 通过其 ID 存储每个季节或剧集的数据,并让组件告诉 vuex 它需要哪个 ID 的数据。当你将不同季节的数据覆盖到同一个 'selectedSeason' 变量中时,你就违背了使用 vuex 的目的。

换句话说,你的四季 vuex 商店看起来像

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

它应该看起来像

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

Clearing the state.selectedSeasonEpisodes and state.selectedSeason manually seems like a "workaround" for something I'm not getting. Should I had put it in there in the first place?

正确——那个逻辑("which season am I displaying?")应该在组件中;它从(大概)路线或另一个组件 prop 获取季节 ID,然后向 vuex 询问该特定 ID 的数据。 vuex 商店不需要关心当前显示给用户的内容。

I've tried putting "selectedSeasonEpisodes" and "selectedSeason" inside the state.series (that have the series info and get cleared everytime a new series page is entered), but I'm getting a lot of errors, as when the series is not loaded yet its value is "null" and properties are undefined.

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

I thought about creating a seasonsEpisodes (plural) instead of selectedSeasonEpisodes that adds up as users click on seasons, sort of like a "cache"

Vuex就是那个缓存;这就是 vuex 存在的原因。如果一个组件请求 vuex 已经有的数据,它可以立即 return 它;如果它请求 vuex 还没有的数据,vuex 可以向服务器请求它。 (这就是为什么你想将 vuex 存储与用户当前视图分离的部分原因;如果 vuex 只包含当前正在使用的内容并在每次请求时覆盖旧数据,你还不如完全跳过 vuex 并让每个组件直接请求数据来自服务器。)

In the above method it displays only the selected season episodes by .find, but the initial state of seasonsEpisodes is undefined so it also generates an error. Should I manually define the initial state as an empty array?

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

如何组织存储完全取决于您,Vue 不会限制您的选择。理解这一点很重要,因为如果不需要,您不需要遵循特定的方案。创建对您的应用 有意义 的存储。

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

如果您征求意见:

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

此外,您可以通过使用 v-if 检查是否存在并将 state arrays/objects 定义为空 arrays/objects 来避免 'empty' 错误。我在这里没有看到问题。

当用户点击另一个系列时 link,您可以检查此信息是否已存在于您的状态(之前已获取),如果是 - 立即显示,如果不存在 - 在获取数据时显示加载动画和推送到您的缓存 array/object.