v-data-table行独立计数器实现及Vuex存储问题求助
解决v-data-table每行独立计数器及Vuex存储问题
问题根源
所有行计数器同步变化,是因为用了一个全局的counter变量,所有行共享同一个值,点击增减按钮时自然会同时改变。要实现每行独立计数器,得给每个币种单独存对应的计数。
解决方案步骤
- 创建独立计数器存储
在组件的data里定义一个对象,用币种的symbol作为唯一键,存储对应行的计数器数值,默认初始值为1:
data() { return { coinCounters: {} // 结构示例: { "BTC": 1, "ETH": 2 } } }, // 获取到币种数据后初始化计数器 mounted() { this.filteredCoins.forEach(coin => { if (!this.coinCounters[coin.symbol]) { this.coinCounters[coin.symbol] = 1 } }) }
- 修改v-data-table模板绑定
把原来的全局counter替换成对应币种的独立计数器,操作时针对当前coin的symbol:
<v-data-table dense :headers="dataTableHeaders" :items="filteredCoins" :items-per-page="5"> <template v-slot:body="{ items }"> <tbody> <tr v-for="coin in items" :key="coin.symbol"> <td>{{ coin.symbol }}</td> <td>{{ coin.lastPrice }}</td> <td> <v-btn icon x-small text @click.stop="coinCounters[coin.symbol]++"> <v-icon>mdi-arrow-up</v-icon> </v-btn> <v-counter :value="coinCounters[coin.symbol] || 1" /> <v-btn icon x-small text @click.stop="coinCounters[coin.symbol] = Math.max(1, coinCounters[coin.symbol] - 1)"> <v-icon>mdi-arrow-down</v-icon> </v-btn> </td> <td v-if="$store.state.portfolio.includes(coin)"> <UpdateDeleteButtons :selected-coin="coin" :count="coinCounters[coin.symbol] || 1"/> </td> <td v-else> <AddButton :selected-coin="coin" :count="coinCounters[coin.symbol] || 1"/> </td> </tr> </tbody> </template> </v-data-table>
注:减按钮加了
Math.max(1, ...)防止计数器变成负数,可根据需求调整最小值。
- 修正AddButton组件的props类型
之前selectedCoin的props类型写的[]是错误的,改成Object:
<script> import { mapActions } from 'vuex'; export default { props: { selectedCoin: { type: Object, required: true }, count: { type: Number, default: 1 } }, name: 'AddButton', methods: { ...mapActions(['saveCoinToPortfolio']), saveCoinToPortfolio() { this.$store.dispatch('saveCoinToPortfolio', {data: this.selectedCoin, count: this.count}) } } } </script>
原理说明
通过coin.symbol作为唯一标识,在coinCounters对象中为每个币种单独存储计数器值,这样每行的增减操作只会修改当前币种对应的数值,不会影响其他行。同时传递给子组件的count也是当前行的独立数值,确保存入Vuex时数据正确。
内容的提问来源于stack exchange,提问作者Abdullah Okay
相关产品推荐
相关产品推荐

