英文:
Getting multiple properties of an object based on matching ID and outputting them without reducing multiple times
问题
I can provide a translation for the code-related part of your text. Here it is:
我好奇是否有更好的方法从Vue <template>或包装DOM元素中的减小对象中获取属性。
例如,在我的组件中,我有这两个数据对象:
```js
player: [{
active: true,
id: 0,
name: "Alfred",
action: 0
}, {
active: true,
id: 1,
name: "Bruce",
action: 1
}],
actions: [{
id: 0,
label: "Give advice",
description: "Player advises others"
}, {
id: 1,
label: "Fight",
description: "Player fights enemy"
}]
... 我想循环遍历一个选项列表,并返回所有结果,其中包括每个玩家内的action属性:
------------------------------------------------------------------
Active? ID Name Label Description
------------------------------------------------------------------
true 0 Alfred Give Advice Player advises others
true 1 Bruce Fight Player fights enemy
我知道我可以像这样循环遍历玩家:
<table>
<tr v-for="(player, index) in players" :key="index">
<td>{{ player.active }}</td>
<td>{{ player.id }}</td>
<td>{{ this.getActionProp(player.action, 'label') }}</td>
<td>{{ this.getActionProp(player.action, 'description') }}</td>
</tr>
</table>
使用这样的方法:
getActionProp(id, prop){
return this.actions.reduce((acc, cur) => {
return cur.id == id ? cur[prop] : acc
}, {})
}
但似乎对于表格中的每一行都需要减少两次。是否有更好的方法来获取这些属性,或者至少使它们在每行中只减少一次?
类似这样的方法:
<table>
<tr v-for="(player, index) in players" :key="index">
<td>{{ player.active }}</td>
<td>{{ player.id }}</td>
<template :action="getAction(player.action)">
<td>{{ action.label }}</td>
<td>{{ action.description }}</td>
</template>
</tr>
</table>
其中 getAction()
是一个减少并返回匹配action对象的方法。
感谢您的时间,我感谢您的指导。
<details>
<summary>英文:</summary>
I'm curious if there's a better way of getting properties from a reduced object within a Vue <template> or wrapper DOM element.
For example, I have these two data objects in my component:
```js
player: [{
active: true,
id: 0,
name: "Alfred",
action: 0
}, {
active: true,
id: 1,
name: "Bruce",
action: 1
}],
actions: [{
id: 0,
label: "Give advice",
description: "Player advises others"
}, {
id: 1,
label: "Fight",
description: "Player fights enemy"
}]
...and I'd like to loop through a list of options and return all results, with properties of the action within each player:
------------------------------------------------------------------
Active? ID Name Label Description
------------------------------------------------------------------
true 0 Alfred Give Advice Player advises others
true 1 Bruce Fight Player fights enemy
I know I can loop through the players like so:
<table>
<tr v-for="(player, index) in players" :key="index">
<td>{{ player.active }}</td>
<td>{{ player.id }}</td>
<td>{{ this.getActionProp(player.action, 'label') }}</td>
<td>{{ this.getActionProp(player.action, 'description') }}</td>
</tr>
</table>
With a method like this:
getActionProp(id, prop){
return this.actions.reduce((acc, cur) => {
return cur.id == id ? cur[prop] : acc
}, {})
}
But it seems like that has to reduce twice for each row in the table. Is there a better way to get these props or at least to make it so they only reduce once per row?
Something like:
<table>
<tr v-for="(player, index) in players" :key="index">
<td>{{ player.active }}</td>
<td>{{ player.id }}</td>
<template :action="getAction(player.action)">
<td>{{ action.label }}</td>
<td>{{ action.description }}</td>
</template>
</tr>
</table>
with getAction()
being a method that reduces and returns the matching action object.
Thank you for your time and I appreciate your guidance.
答案1
得分: 2
你可以只需映射计算中的操作并准备表格行:
<script setup>
import { computed, reactive } from 'vue'
const players = reactive([{
active: true,
id: 0,
name: "Alfred",
action: 0
}, {
active: true,
id: 1,
name: "Bruce",
action: 1
}])
const actions = reactive([{
id: 0,
label: "Give advice",
description: "Player advises others"
}, {
id: 1,
label: "Fight",
description: "Player fights enemy"
}])
const playerTable = computed(() => players.map(player => {
return {
...player,
action: actions.find(action => action.id === player.action)
}
}))
</script>
<template>
<h1>TEST</h1>
<table>
<tr v-for="player in playerTable" :key="player.id">
<td>{{ player.active }}</td>
<td>{{ player.id }}</td>
<td>{{ player.action.label }}</td>
<td>{{ player.action.description }}</td>
</tr>
</table>
</template>
英文:
You can just just map the actions in a computed and prepare the table rows:
<script setup>
import { computed, reactive } from 'vue'
const players = reactive([{
active: true,
id: 0,
name: "Alfred",
action: 0
}, {
active: true,
id: 1,
name: "Bruce",
action: 1
}])
const actions = reactive([{
id: 0,
label: "Give advice",
description: "Player advises others"
}, {
id: 1,
label: "Fight",
description: "Player fights enemy"
}])
const playerTable = computed(() => players.map(player => {
return {
...player,
action: actions.find(action => action.id === player.action)
}
}))
</script>
<template>
<h1>TEST</h1>
<table>
<tr v-for="player in playerTable" :key="player.id">
<td>{{ player.active }}</td>
<td>{{ player.id }}</td>
<td>{{ player.action.label }}</td>
<td>{{ player.action.description }}</td>
</tr>
</table>
</template>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论