【问题标题】:How to create data structure that supports carousel behavior?如何创建支持轮播行为的数据结构?
【发布时间】:2021-02-10 02:09:20
【问题描述】:

这是一个简单的 Vue.js 测试应用程序,代码如下:

<template>
  <div>
    <button @click="onPrevious">Previous</button>
    <button @click="onNext">Next</button>
    <br><br>
    <div v-for="(a, index) in chunkedArr()" :key="index">
      <div v-for="(i, index) in a" :key="index">{{ i }}</div>
      -
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
      newInput: [],
      currentIndex: 0
    }
  },
  mounted() {
    const temp = []

    for (let i = 0; i < this.input.length; i += 3) {
      let chunk = this.input.slice(i, i + 3)
      if (chunk.length === 1) {
        chunk = chunk.concat(this.input.slice(0, 2))
      }
      if (chunk.length === 2) {
        chunk = chunk.concat(this.input.slice(0, 1))
      }
      temp.push(chunk)
    }
    this.newInput = temp.flat()
  },
  methods: {
    chunkedArr() {
      if (this.newInput.length === 0) {
        return
      }

      const output = []

      for (let i = this.currentIndex; i < this.newInput.length; i += 3) {
        let chunk = this.newInput.slice(i, i + 3)
        output.push(chunk)
      }

      console.log(output)

      return output
    },
    onNext () {
      this.chunkedArr()
    },
    onPrevious () {
      // TODO
    }
  },
}
</script>

我们可以使用 Next 和 Previous 按钮模拟轮播。假设我们有一些应该在轮播中显示的元素数组。

但是,在这个轮播中,我们应该一次显示 3 个元素。这意味着只有在每次单击 Next/Previous 时才能看到 3 个元素。例如,如果我们有一个元素数组:1、2、3、4、5、6、7、8、9、10、11,则初始状态为显示:1、2、3。第一次单击下一步时,轮播应显示 4、5、6 等。数组末尾有 3 个案例。数组末尾可以有 1、2 或 3 个元素。如果它有 3 个元素,那么一切都很容易。但是如果它有 1 个或 2 个元素,我们需要分别添加 2 个或 1 个元素。如果最后有 1 个元素,我们需要添加数组的前 2 个元素以显示 3 个元素。如果最后有 2 个元素(我们的测试用例),我们只需要添加第一个元素才能显示 3 个元素。轮换应该根据之前描述的场景进行。

请看一下所附截图:

在实际情况下,我需要 BootstrapVue 的 Carousel 的数据结构。

更新:

输出数组中有 4 个子数组。请看下面的截图:

更新:

【问题讨论】:

  • 您说的是子数组,但在您的输出示例中没有子数组。只需双倍空格而不是嵌套 []。你应该说清楚..
  • 如果没有元素丢失怎么办。 newInput 还是一样的吗?
  • 如果元素没有丢失,数组可能如下所示:1,2,3,4,5,6,7,8,9,10,11,12。也就是说,我们立即拥有所有包含 3 个元素的子数组。

标签: arrays vue.js


【解决方案1】:

const example = [1, 2, 3, 4, 5];
const subArrayIterator = subArrayGenerator(example);
console.log('init: ' + subArrayIterator.next().value); // init

const prevBtn = document.getElementById('prev');
const nextBtn = document.getElementById('next');
prevBtn.onclick = () => {
  console.log(subArrayIterator.next(false).value);
}
nextBtn.onclick = () => {
  console.log(subArrayIterator.next().value);
}

function* subArrayGenerator(inputArray, subArrayLength=3) {
  let prev = false;
  for (let i = 0; i < inputArray.length;) {
    if (prev) {
      let diff = subArrayLength*2;
      if (diff > inputArray.length) {
        diff = diff % inputArray.length;
      }
      diff = i - diff;
      i = diff < 0 ? inputArray.length + diff : diff;
    }
    const subArray = [];
    for (let j = 0; j < subArrayLength; j++) {
      subArray.push(inputArray[i]);
      i = i < inputArray.length - 1 ? i + 1 : 0;
    }
    prev = (yield subArray) === false;
  }
}
<button type="button" id="prev">prev</button>
<button type="button" id="next">next</button>

【讨论】:

  • 很抱歉,很可能我在第一篇文章中没有清楚地描述我需要什么。请查看更新后的帖子。
  • @tesicg 你为什么谈到 F5?
  • 我尝试过进行某种轮播模拟,但我认为最好使用“下一个/上一个”按钮。
  • 如果输入数组如下所示: const example = [1, 2, 3, 4, 5];当我们上一个时,三元组中有一个“空”值。请查看原帖中的更新部分。
  • 我已将:const diff = i - (subArrayLength * 2) 更改为:const diff = i - ((subArrayLength - 3) * 2) 我认为我在上一个得到了正确的结果: [1,2,3], [4,5,1], [2,3,4], [5,1,2], [3,4,5], [1,2,3]...
【解决方案2】:

另一种方法:

  1. 通过将inputsplice0 附加到currentIndex 来旋转数组:

    input.push(...input.splice(0, currentIndex))
    
  2. 通过将 inputslice0 附加到填充长度,将数组填充到最大长度 12:

    while (12 - input.length > 0) {
      input.push(...input.slice(0, 12 - input.length))
    }
    
  3. Array(size).fill().map() 将数组分成 3 个切片:

    const output = Array(Math.ceil(input.length / 3)).fill().map((_, i) => input.slice(i * 3, i * 3 + 3))
    

demo

【讨论】:

  • 很抱歉,很可能我在第一篇文章中没有清楚地描述我需要什么。请查看更新后的帖子。
  • 数组不限于12个元素。它可以包含很多元素。
猜你喜欢
  • 1970-01-01
  • 2020-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2017-01-25
相关资源
最近更新 更多