VUE 动画演示冒泡排序实现原理

168 阅读1分钟

用VUE做了一个冒泡排序的动画。

demo01.gif

直接复制代码就可以用啦。for循环里用了await this.sleep(1000)相当于定时器。然后根据id来修改样式做交换的动画。感觉这块代码有点挫了。欢迎给出修改意见

<template>
  <!-- 冒泡排序演示 -->
  <div class="marginCenter demoBox">
    <h2 class="demoh2">冒泡排序演示</h2>
    <h4 class="demoh4">冒泡排序,从大到小排序。输入框中<span :class="!ischeck ? 'redword' : ''">输入1到20的数字以空格分隔</span>。</h4>
    <h4 class="demoh4">点击'开始表演'后开始动画演示,红色会与绿色进行对比。</h4>
    <h4 class="demoh4">如果红色小于绿色,他们会交换位置。如果红色大于绿色,他们位置不变。</h4>
    <div class="demoHeader">
      <input type="text" v-model.trim="input" placeholder="请输入数字 以空格分隔">
      <div @click="showTime" class="button">开始表演</div>
    </div>
    <div class="arrList" ref="arrList">
      <div class="arrItem" :id="'arrItem' + index" v-for="(item, index) in arr" :key="index">
        <div class="arrContent" :id="'arrContent' + index" :style="{'height': 5*item + '%'}"></div>
        <div class="arrtext" :id="'arrtext' + index">{{item}}</div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'demo01',
  data () {
    return {
      input: '11 1 17 3 14 6 19 8',
      arr: [11, 1, 17, 3, 14, 6, 19, 8],
      ischeck: true,
      isShowAgain: true
    }
  },
  mounted () {
  },
  methods: {
    sleep (time) {
      return new Promise((resolve) => setTimeout(resolve, time))
    },
    showTime () {
      if (!this.isShowAgain) { return false }
      this.ischeck = true
      var re = /\b([1-9]|1[0-9]|20)\b/
      let newarr = this.input.split(' ')
      newarr.map(v => {
        if (!re.test(v)) {
          this.ischeck = false
          return false
        }
      })
      if (!this.ischeck) { return false }
      this.arr = this.input.split(' ')
      this.arr = this.arr.map(Number)
      this.isShowAgain = false
      this.bubbleSort(this.arr)
    },
    async bubbleSort (arr) {
      var len = arr.length
      for (let i = 0; i < len; i++) {
        for (let j = 0; j < len - 1 - i; j++) {
          var k = j
          var l = k + 1
          document.getElementById('arrItem' + k).classList.add('red')
          document.getElementById('arrItem' + l).classList.add('green')
          await this.sleep(1000)
          if (arr[j] < arr[j + 1]) {
            var temp = arr[j + 1]
            arr[j + 1] = arr[j]
            arr[j] = temp
            document.getElementById('arrItem' + k).classList.add('moveRight')
            document.getElementById('arrItem' + l).classList.add('moveLeft')
            await this.sleep(500)
            document.getElementById('arrContent' + l).style.height = 5 * (arr[j + 1]) + '%'
            document.getElementById('arrtext' + l).innerHTML = arr[j + 1]
            document.getElementById('arrContent' + k).style.height = 5 * (arr[j]) + '%'
            document.getElementById('arrtext' + k).innerHTML = arr[j]
            document.getElementById('arrItem' + k).classList.remove('moveRight')
            document.getElementById('arrItem' + l).classList.remove('moveLeft')
          }
          document.getElementById('arrItem' + k).classList.remove('red')
          document.getElementById('arrItem' + l).classList.remove('green')
        }
      }
      this.isShowAgain = true
      this.arr = arr
    }
  }
}
</script>

<style lang="less">
.demoHeader{
  margin-top: 20px;
  display: flex;
  align-items: center;
  input{
    height: 32px;
    font-size: 20px;
    margin-right: 20px;
    width: 300px;
    border: 1px solid #cccccc;
    border-radius: 4px;
  }
}
.arrList{
  display: flex;
  margin-top: 30px;
  .arrItem{
    width: 60px;
    height: 200px;
    border: 1px solid var(--black);
    margin-right: 20px;
    position: relative;
    .arrContent {
      background: var(--button);
      position: absolute;
      width: 100%;
      bottom: 0;
    }
    .arrtext {
      position: absolute;
      bottom: -30px;
      width: 100%;
      text-align: center;
    }
  }
  .red {
    .arrContent {
      background: var(--red);
    }
  }
  .green {
    .arrContent {
      background: var(--green);
    }
  }
  .moveRight {
    animation: moveright 0.55s infinite;
  }
  .moveLeft {
    animation: moveleft 0.55s infinite;
  }
  @keyframes moveright
  {
    from {transform: translate(0px, 0px);}
    to {transform: translate(82px, 0px);}
  }
  @keyframes moveleft
  {
    from {transform: translate(0px, 0px);}
    to {transform: translate(-82px, 0px);}
  }
}
</style>