一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器

起因

  女朋友说要写个学习记录博客,有关冒泡排序的,想用图片的方式来展示冒泡排序的过程以便理解。
  她一开始准备用PS来做图片,一张图一张图P过来,哇,想想都觉得累。
  可能是我PS水平一般吧,我第一个想到的就是我写个简单的网页就完事咯。
  所以,我准备用刚学的Vue知识给她做了一个冒泡排序的过程展示器网页。

1.初步需求分析

  我粗略的想了一下,感觉需求应该分两部分:
  1.模拟冒泡排序
  2.准备如何在博客里展示过程

1.1 模拟冒泡排序

  怎么模拟冒泡排序?
  冒泡排序熟悉呀,这个问题也简单。

先想想冒泡排序的原理:
  游标i从数组头部开始,比较游标i与i+1在数组所指向的数,若前者大于后者,交换两个数的位置,然后游标i往后移一位。
  循环上述操作,直到比较完整个数组,最大的数就会放到数组尾部。
  每确定一个最大的数算作一轮。
  新的一轮需要在未确定数中再找出一个最大的数,放在前一轮找到数的前一位。
  一轮一轮下来,直到未确定数只有一个,冒泡排序到此为止。数组就会按从小到大的顺序排序了。

如何模拟:
  将冒泡排序中的每种操作都拿出来,让他们能逐步执行。
  分析了一下冒泡排序的原理,我找到的操作有:
  1.比较游标i与i+1在数组所指向的数,若前者大于后者,交换两个数的位置。
  2.游标i往后移一位。
  3.每一轮的操作,也就是:不断循环操作1与操作2,直到比较完整个数组。
  4.除去已确定的数,用剩下的未确定数开始新的一轮。
  5.整个冒泡排序的操作,也就是不断循环操作3、操作4,直到未确定数只有一个。

  有上面的五个操作,我们也就能把冒泡排序的过程给模拟出来了。

1.2 博客里准备如何展示过程

  数组里的数字用小框框框好,并排放置。
  游标i与i+1都要显示,显示在数字框的上方。
  每次游标移动、数字换位以及每轮结束、排序结束都可以显示相应的提示语。提示语显示在数字框下方。

2.具体实现

  上面初步进行了一番需求分析后,我就马上开始准备写代码了。

2.1 模拟冒泡排序

  从模拟冒泡排序开始吧。

2.1.1 网页框架

  先弄个小框架,把模拟冒泡排序里的五个操作写进methods。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第1张图片

2.1.2 实现五个操作

  就按从上往下的顺序写吧~

compare方法

需求:比较游标i与i+1在数组所指向的数,若前者大于后者,交换两个数的位置。

所需数据
  destArray – 首先,我们需要一个Array变量来存储我们需要排序的数组。
  cursorIndex – 还需要一个Number变量来存储游标i在destArray中的索引值。

实现方法分析
  游标i所指的数就是destArray[cursorIndex],
  i+1所指的数就是destArray[cursorIndex+1]
  两者对比就行。

JS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第2张图片

goToNext方法

需求:游标i往后移一位。

所需数据:cursorIndex,destArray,
currentRound – 需要一个Number变量来存储当前的轮数,从1开始计算。其实也等于(已确定数的数量加1)。

实现方法分析
  这里只需要把cursorIndex++就行了。
  但是我们还要考虑到一个情况,cursorIndex肯定不可以一直加上去,我们的数组是有长度限制的,作为其中的索引,是不可以超出的。
  而且,我们前面定义了每次比较i与i+1所指向的数,直到比较完整个数组(这个数组是除去已确定数后剩下的未确定数组成的)。
  也就是说,i指向数组倒数第二个数时,就已经比较完了。
  由于i == 0时,指向的是数组第一个数,所以i == 数组长度 - 2时,指向的是数组倒数第二个数。
  所以i的取值范围应该是0到(数组长度 减2 再减 已确定数的数量)。
  数组长度减2再减已确定数的数量 =destArray.length - 2 - (currentRound - 1) = destArray.length - currentRound - 1。

JS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第3张图片
在这里插入图片描述

runRound方法

需求:每一轮的操作,也就是:不断循环操作1与操作2,直到比较完整个数组。

所需数据:destArray,cursorIndex,currentRound

所需方法:compare(),goToNext()

实现方法分析
  需求里所谓的整个数组,也是未确定数组成的数组。
  根据规则,每一轮的操作,就是比较i和i+1,i++;比较i和i + 1,i++;…直到i到了倒数第二个数时,只需要比较i和i + 1而不需要再让i++了。
  所以,i的取值范围依旧是0到destArray.length - currentRound - 1。
  当cursorIndex == 0 ~ destArray.length - currentRound - 2时,先执行compare(),再执行goToNext(),
  当cursorIndex == destArray.length - currentRound - 1时,只执行compare()。

JS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第4张图片

goToNextRound方法

需求:开始新的一轮。

所需数据:destArray,cursorIndex,currentRound

实现方法分析
  开始新的一轮,那就是说我们需要把参数的状态调整到新的一轮时该有的状态。
  新一轮的状态需要改变的参数有哪些呢?
  cursorIndex,我们需要让游标回到数组的头部,这样才可以开始新一轮的比较。
  currentRound,这个参数既然表示了当前的轮数,那轮数增加了,他也需要增加。
  这里我们需要注意的是,轮数是有限的,currentRound不可能一直加下去。
  找到定义,直到未确定数只有一个了,冒泡排序结束。
  未确定数的数量 = 数组长度 - 已确定的数 = destArray.length - (currentRound - 1)。
  那destArray.length - (currentRound - 1) == 1的时候,才代表冒泡排序结束了?其实不是的。
  实际情况的时候,在剩最后两个数时,我们调用compare()后,冒泡排序就结束了,不需要再调用一次goToNextRound()让未确定数的数量变成一个时才判定排序结束。
  也就是destArray.length - (currentRound - 1) == 2时,再执行完一次compare(),排序结束。
  所以,currentRound的取值范围就是1到destArray.length - 1。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第5张图片

runBubbleSort方法

需求:整个冒泡排序的操作,也就是不断循环操作3、操作4,直到剩下的数只有一个。

所需数据:destArray,cursorIndex,currentRound

所需方法:runRound(),goToNextRound()

实现方法分析
  如上个方法中分析的,在剩最后两个数时,我们调用compare()后,冒泡排序就结束了,不需要再调用一次goToNextRound()。
  在这之前,都是需要runRound(),goToNextRound();runRound(),goToNextRound();…直到剩最后两个数。
  在剩最后两个数时,调用一次compare()起到的效果,其实就等于调用一次runRound()。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第6张图片

2.2 解决博客展示需求

  博客的展示需求共有三个,一个一个来解决。
  但首先要做的是需要设置一个区域来应用我们的Vue对象。
  第一步,创建一个id为main的div。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第7张图片
  第二步,把刚刚创建的div的选择器语句赋值给Vue对象的el属性。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第8张图片
  搞定!

2.2.1 博客展示需求一

需求:数组里的数字用小框框框好,并排放置。

所需数据:destArray

实现方法分析
  设置一个div作为数字框的父容器。
  再将这个div样式中的display属性设置为flex,就可以实现数字框的并排放置。
  数字框可以用v-for特性来批量生成。

HTML改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第9张图片
CSS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第10张图片
运行结果
在这里插入图片描述
  数字都按顺序显示出来了,而且是并排放置的。但是,这挤一团也太丑了。稍微给数字框加点样式。

CSS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第11张图片
运行结果
在这里插入图片描述

2.2.2 博客展示需求二

需求:游标i与i+1都要显示,显示在数字框的上方。

所需数据:cursorIndex

实现方法分析
  游标的显示,可以利用css中的伪类:after或者:before来实现。
  我们给游标i和i+1所指的数字框添加相应的class,然后给这两个class都设置一个伪类:after,用这个伪类来实现i和i+1的显示。
  那只需要动态的改变数字框的class,就可以实现i和i+1的移动。
  使用Vue的class绑定 v-bind:class,来实现动态改变数字框的class。
  再利用v-for中的索引参数来决定class是否绑定。

HTML改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第12张图片
CSS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第13张图片
运行结果
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第14张图片
  为了让i以及i+1能放到想要的位置,在css中添加的属性还是较多的,需要注意,别落了。
  其中有一个比较实用:right加transform来实现:after伪类的绝对定位水平居中

2.2.3 博客展示需求三

需求:每次游标移动、数字换位以及每轮结束、排序结束都可以显示相应的提示语。提示语显示在数字框下方。

所需数据
  tips – String变量来存储提示语

所需方法:compare(),goToNextRound(),goToNext()

实现方法分析
  需要设置一个div来放置提示语,这个div放在数字框列表div的下方。
  完成相应操作后,要改动相应的提示语。
  每轮结束和排序结束的最后一步其实都是compare(),所以他们的提示语可以直接整合到compare()中。

HTML改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第15张图片
JS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第16张图片
  这里的tips初始值为"Tips"是为了方便看tips-box的样式效果,实际使用时需要设为空字符串。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第17张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第18张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第19张图片
CSS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第20张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第21张图片
运行结果
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第22张图片

2.3 控制展示

  Vue的绑定机制,可以让我们只需要修改相应变量的数值就能同步修改HTML内容。
  看一下我们前面做的准备:
  数字框列表依赖v-for与Vue对象中的destArray绑定。
  i和i+1的位置依赖v-bind:class与Vue对象中的cursorIndex绑定。
  提示语内容与Vue对象中的tips绑定。
  我们模拟冒泡排序的五个操作,也是直接去修改destArray、cursorIndex、tips的数值。

  所以,我们只需要放置五个按钮,分别绑定冒泡排序的五个操作,靠点击按钮,就能实现控制展示内容。

HTML改动
  在tips-box底下添加一个hr标签来划分区域,然后再添加一个button-list。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第23张图片
CSS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第24张图片

2.4 最后成果&发现问题

一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第25张图片
  具体每个按钮触发后的情况,要贴的图有点多,就不贴了。
  总之,按上面的代码实现下来,每个按钮的功能规范操作的话,都是能照预期进行的。

不过问题也是存在的。
问题1
  runRound()和runBubbleSort()因为没有设置延迟,所以点击之后,直接把最终结果呈现出来了,中间过程全部跳过。
  这里就得看需求了,需不需要中间的过程,需要的话,我们还需要去设置延迟。
问题2
  按照逻辑来讲,GoToNext按钮必须在Compare按钮点击之后才可以点击。
  GoToNextRound按钮必须在RunRound按钮点击之后,或者这轮最后一次compare()方法执行之后才可以点击。
  对这两个按钮,我们也需要做一定的操作限制。
问题3
  使用的舒适度还欠佳。实际使用的时候,不能返回上一步,也不能重置数组,这就会使得操作失误的时候,想要重归正轨就很麻烦。
  数组数据也还不能在网页上自定义改动,不够灵活。

3.总结

  这里算是把最基础的需求给完成了,就是后续还需要优化呢。
  下篇博客再来谈谈优化相关的内容吧,这篇我感觉写得已经太长了。

  再说说写这篇博客写下来的感觉。
  不得不说,之前没怎么写过这样萌新向的文章,真的想象不到原来写一篇这样的文章需要花这么多时间。
  上面的代码包括后续的优化代码,半小时可能都没到就已经写完了。
  但是写这篇文章,包括要构思如何来展示内容、代码介绍要分哪几块来些、怎么把写的时候的思路表述出来等等,花了好几个小时来回折腾才完成。
  不过这次也算是获得了不少经验吧,下次的写作速度一定会有所提高的!也希望自己的表述能力也能不断进步!

  还有一点要吐槽一下,Markdown编辑器要实现首行缩进好麻烦啊,得自己手动在每个首行都添加“  “,好怕哪一行忘了加,就难受了。

你可能感兴趣的:(前端,一块学Vue)