Vue3 排序计算数组
Vue3 sort computed array
我目前正在使用 Vue3 开发一款带有自上而下地图和单位的游戏。我有一个单位商店,我将所有单位对象保存在一个数组中,每个单位都根据其坐标放置在地图上。
我的商店中有一种方法可以检索同一坐标上的所有单位:
public getUnitsAt(coordinates: Coordinates): Array<Unit> {
return this.state.units.filter((unit) => unit.coordinates.x === coordinates.x && unit.coordinates.y === coordinates.y);
}
在大多数情况下,这足以在列表中显示这些单位。现在,我介绍了具有自己的城镇视图组件的城镇,并且我想显示城镇“外部”但仍在同一坐标上的单位。所以我用这个:
const outsideUnits = computed(() => unitStore.getUnitsAt(town.coordinates));
到目前为止一切顺利,但现在我希望能够通过告诉特定单元移动到前面来对这些外部单元进行排序。问题是这个数组已经是存储中过滤后的数组副本。所以我可能可以对这个计算出的 属性 进行排序,但是一旦将另一个单元添加到商店,它就会重新计算,我的订单就会丢失。有什么想法我仍然可以拥有最新的单位数组,但能够排序吗?
如果一个单位从附近的场地移动到同一场地,它应该自动在前面。
根据您关于内存是一个次要问题的评论,我认为这 problem/solution 就像一个文档存储 noSQL DB,其中优化针对读取,这意味着完成了更多工作 up-front 在写入时(有时在多个地方更新相同的数据)因为写入的频率低于读取的频率。
一些注意事项
- 一个方法,例如
getUnitsAt
,结果不会被缓存,所以每次调用它时都会 运行 函数。
- 想要数据持久化,就需要存储起来。
我建议使用一个计算值,将所有相关 tiles 的信息存储在一个对象中。
例如 unitOrder['12_6']
将 return [unit6, unit3, unit4]
,其中 12_6
将是 x 和 y 坐标。 (但最好通过 posToKey = (x,y)=> [x,y].join('_')
之类的方法抽象索引查找)
诀窍是维护单位顺序,因此只要任何单位的位置发生变化,就需要更新之前和最后的位置。可以在仅跟踪具有多个单元的图块的情况下进行优化,并且通过一种可以处理丢失的位置键的方法来抽象查找。限制 Vue 反应性的使用也可能是值得的,因为它可能会增加不需要的开销(YMMV);例如,如果你依赖于一个变化,而不是让 unitOrder
反应,你可以做一个反应 outsideUnitsChanged = ref(0)
变量,只要有实质性的变化就会保持递增。这将防止触发多个更新(当您从一个位置删除单元并在添加它时再次触发)
希望这是有道理的。
TSU,我会保留数据结构 non-reactive,并且只使用 Vue 作为表示数据的方式。
我目前正在使用 Vue3 开发一款带有自上而下地图和单位的游戏。我有一个单位商店,我将所有单位对象保存在一个数组中,每个单位都根据其坐标放置在地图上。 我的商店中有一种方法可以检索同一坐标上的所有单位:
public getUnitsAt(coordinates: Coordinates): Array<Unit> {
return this.state.units.filter((unit) => unit.coordinates.x === coordinates.x && unit.coordinates.y === coordinates.y);
}
在大多数情况下,这足以在列表中显示这些单位。现在,我介绍了具有自己的城镇视图组件的城镇,并且我想显示城镇“外部”但仍在同一坐标上的单位。所以我用这个:
const outsideUnits = computed(() => unitStore.getUnitsAt(town.coordinates));
到目前为止一切顺利,但现在我希望能够通过告诉特定单元移动到前面来对这些外部单元进行排序。问题是这个数组已经是存储中过滤后的数组副本。所以我可能可以对这个计算出的 属性 进行排序,但是一旦将另一个单元添加到商店,它就会重新计算,我的订单就会丢失。有什么想法我仍然可以拥有最新的单位数组,但能够排序吗?
如果一个单位从附近的场地移动到同一场地,它应该自动在前面。
根据您关于内存是一个次要问题的评论,我认为这 problem/solution 就像一个文档存储 noSQL DB,其中优化针对读取,这意味着完成了更多工作 up-front 在写入时(有时在多个地方更新相同的数据)因为写入的频率低于读取的频率。
一些注意事项
- 一个方法,例如
getUnitsAt
,结果不会被缓存,所以每次调用它时都会 运行 函数。 - 想要数据持久化,就需要存储起来。
我建议使用一个计算值,将所有相关 tiles 的信息存储在一个对象中。
例如 unitOrder['12_6']
将 return [unit6, unit3, unit4]
,其中 12_6
将是 x 和 y 坐标。 (但最好通过 posToKey = (x,y)=> [x,y].join('_')
之类的方法抽象索引查找)
诀窍是维护单位顺序,因此只要任何单位的位置发生变化,就需要更新之前和最后的位置。可以在仅跟踪具有多个单元的图块的情况下进行优化,并且通过一种可以处理丢失的位置键的方法来抽象查找。限制 Vue 反应性的使用也可能是值得的,因为它可能会增加不需要的开销(YMMV);例如,如果你依赖于一个变化,而不是让 unitOrder
反应,你可以做一个反应 outsideUnitsChanged = ref(0)
变量,只要有实质性的变化就会保持递增。这将防止触发多个更新(当您从一个位置删除单元并在添加它时再次触发)
希望这是有道理的。
TSU,我会保留数据结构 non-reactive,并且只使用 Vue 作为表示数据的方式。