<template>
<div class="number-picker">
<button @click="selectPrevious" :disabled="circularIndex === 0">上一个</button>
<div class="number-list">
<span
v-for="(number, index) in visibleNumbers"
:key="number"
:class="{ 'selected': circularIndex === index + startIndex }"
@click="selectNumber(number)"
>
{{ number }}
</span>
</div>
<button @click="selectNext" :disabled="circularIndex === numbers.length - 1">下一个</button>
</div>
</template>
<script>
export default {
data() {
return {
numbers: [1, 2, 3, 5, 7, 8, 9, 14, 15, 17, 22, 25, 26],
circularIndex: 5, // 初始选中17(数组索引为5),用于循环
visibleNumbers: [],
startIndex: 0, // 可见列表的起始索引
};
},
computed: {
// 无需计算,因为我们已经有了circularIndex
},
watch: {
// 监听circularIndex的变化,并更新visibleNumbers
circularIndex(newValue) {
this.updateVisibleNumbers();
},
},
methods: {
// 切换到上一个数字(循环)
selectPrevious() {
this.circularIndex = (this.circularIndex - 1 + this.numbers.length) % this.numbers.length;
},
// 切换到下一个数字(循环)
selectNext() {
this.circularIndex = (this.circularIndex + 1) % this.numbers.length;
},
// 选择数字(主要用于点击列表中的数字)
selectNumber(number) {
const index = this.numbers.indexOf(number);
if (index !== -1) {
this.circularIndex = index;
}
},
// 更新显示的数字列表
updateVisibleNumbers() {
const endIndex = Math.min(this.circularIndex + 4, this.numbers.length - 1);
this.startIndex = Math.max(0, endIndex - 7); // 保持显示8个数字
this.visibleNumbers = this.numbers
.slice(this.startIndex, endIndex + 1)
.concat(this.numbers.slice(0, this.startIndex)); // 如果需要,从开头继续取
// 但由于我们只显示8个,所以不需要上面的concat部分,除非有特殊需求
// 直接截取即可
this.visibleNumbers = this.numbers.slice(this.startIndex, this.startIndex + 8);
},
},
mounted() {
// 组件挂载时初始化visibleNumbers
this.updateVisibleNumbers();
},
};
</script>
<style scoped>
/* ... 样式与之前相同 ... */
</style>
注意:上面的代码中,我保留了 concat
方法的注释部分,但实际上在这个场景下我们不需要它,因为我们已经通过调整 startIndex
和直接截取8个元素来确保 visibleNumbers
总是包含以 circularIndex
为中心的8个元素(如果可能的话)。
另外,请注意,我修改了 selectPrevious
和 selectNext
方法以支持循环列表。现在,当点击“上一个”按钮时,如果当前是列表的第一个元素,它会跳到列表的末尾;同样,点击“下一个”按钮时,如果当前是列表的最后一个元素,它会跳到列表的开头。
最后,我移除了 selectedIndexRelativeToVisible
计算属性,因为它在这个修正后的版本中不再需要。我们使用 circularIndex
和 startIndex
来确定哪个数字是选中的,并相应地更新 visibleNumbers
。