一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化

前言

  前文对最初版本冒泡排序过程展示器做了第一次的优化,详见:
  一块学Vue:学习日记_2020.1.7 - 利用Vue实现冒泡排序的过程展示器_第一次优化https://blog.csdn.net/qq493919692/article/details/103838819
  既然有了这一篇文章说明上一次优化后又遗留了一部分问题需要解决。
  前文最后也提到了大致的解决方案:重新申请一个变量作为当前操作状态的标识符,然后把所有操作相关方法以及按钮的控制依赖这个标识符重写一遍逻辑。
  等于说进行了一次小的重构。
  听起来很麻烦,但其实也还好,毕竟只是一个小工具的程序,需要修改的代码又能有多少呢,是吧。
  OK,接下来马上开始!

1.重构

  先不管前文留下的几个问题,我们先把现有的功能重构。

1.1重构数据部分

一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第1张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第2张图片
  这里把这么多属性通过计算属性的方式绑定给state,在性能方面还是有待商榷的。state每次改动,所有的属性都需要重新计算一次,这比把按钮控制直接放在下面操作方法代码中性能消耗大多了。但是放在操作方法代码中的话,管理和维护就很麻烦。
  然后这里我有想到过另一种写法,不写这么多逻辑判定,因为这样看起来也很不清晰。
  比如:

this.state == 5 || this.state == 9 || this.state == 0 ? true : false;

  可以改成

[5, 9, 0].indexOf(this.state) != -1?true : false;

  下面这种写法感觉上维护更容易,但还是那个问题,不知道性能上的表现如何。所以还是没有直接使用。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第3张图片
  这里不再直接用Object.assign()去修改$data来达到恢复初始状态的目的。出于性能以及安全等方面的考虑,包括下面的recordHistory(),back(),restart()都放弃了直接对$data做操作。

1.2 重构方法部分

在这里插入图片描述
  新写了一个方法,用于修改state。为什么要用这个方法呢,因为后面经常会出现一段代码:

if(this.state!= 5 && this.state != 9){
	this.state = 3;//这里的3只是其中一种情况,还可能是其他一些数字
}

  这样写看起来也没什么问题,但是要写的次数多了,就感觉很麻烦了。
  所以我保留了isAuto这个计算属性,再结合setState(),上面的代码就可以改成:

!this.isAuto && this.setState(3); 

  很舒服!
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第4张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第5张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第6张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第7张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第8张图片
  这里把runRound和runBubbleSort完成后的状态修改操作整合到了compare()中。
  考虑到runRound()就是由compare()和goToNext()组成的,runBubbleSort()就是由runRound()和goToNextRound()组成的。所以recordHistory()只在compare()、goToNext()、goToNextRound()中被调用。
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第9张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第10张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第11张图片
  这里放弃了直接对$data做操作后,需要注意的是,Array类型的变量也是属于对象类型的,所以在做赋值操作前,要注意调用concat([])来形成一个新的数组对象。

2.解决遗留问题

  问题1:RunRound和RunBubbleSort结束后,点击Back按钮,会直接跳回到按钮点击前的状态,而不是冒泡排序操作流的前一步状态。
  问题2:按钮启用\禁用状态的控制很杂乱,语句东一句西一句,不方便管理修改与进一步开发。
  问题3:runRound()函数就从调用compare()开始的,如果现在处在刚点完compare()的状态,其实这一次compare()的调用会很多余。同样,runBubbleSort()是从runRound()开始的,如果刚点完runRound()的状态,这次调用也会很多余。
  问题2前面已经解决了,下面就解决一下问题1和问题3。

2.1 问题一

需求:RunRound和RunBubbleSort结束后,点击Back按钮,跳回到冒泡排序操作流的前一步状态。

所需数据
  preState – Number变量,用于存储上一个状态值,初始值为0。

实现方法分析
  点击Back按钮,无法跳回到冒泡排序操作流程的前一步,主要是因为在RunRound或RunBubbleSort进行时,我们禁止了state的修改操作。
  state控制了按钮的启用\禁用状态,所以不能被修改,我们这里只能新添一个变量preState来存储上一个状态值。使用preState其实相当于runRound和runBubbleSort的状态不需要记录了,我们只需要考虑compare、goToNext、goToNextRound的状态就行。也就是状态值为0,1,2,3,4,7,8的时候。
  recordHistory()记录的state值,也由preState取代。

JS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第12张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第13张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第14张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第15张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第16张图片

2.2 问题三

需求:根据状态不同,优化runRound()和runBubbleSort()。

所需数据:this.preState

实现方法分析
  runRound()中要考虑:当preState为2,也就是compare完成后的状态时,跳过compare(),直接调用goToNext()。
  runBubbleSort()中要考虑:当preState为6,也就是runRound完成后的状态时,跳过runRound(),直接调用goToNextRound()。

JS改动
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第17张图片
一块学Vue:学习日记 - 利用Vue实现冒泡排序的过程展示器_第二次优化_第18张图片
  这里呢,按照前面把if语句改成&&语句的情况,应该会给compare、goToNext、goToNextRound都加一个回调函数,然后把if-else结构换成三元运算的结构。
  例如:

this.preState != 2 ? this.compare(()=>{
	this.setTimerRound = setTimeout(() => {
		this.goToNext(()=>{
			this.setTimerRound = setTimeout(() => {
				this.runRound(cb);
			}, 1000);
		})
	}, 1000)
}) : this.goToNext(()=>{
	this.setTimerRound = setTimeout(() => {
		this.runRound(cb);
	}, 1000);
});

  emmmm,回调一多其实看起来就会烦了,这里再改成三元运算的形式,回调就更多了,感觉上就是理解起来比if-else结构要困难一些。考虑到方便理解的情况,在实际代码中,就没有用三元运算的形式来实现。

3.总结

  冒泡排序的过程展示器暂时就算完成了,虽然我还没做过多详细的测试,还会不会存在bug还不好说,XD。总之,简单的测试下来感觉还是没问题的,代码也算优化到了自己感觉比较舒服的样子。接下来就要继续回到Vue官方文档学习相关的博客编写中去了。

  惯例,最后还是得再想想看,还有什么问题吧。我能想到的是有两个。
  问题1,state在频繁改动的情况下,一堆按钮控制变量需要跟着改动,在性能上表现会不会不太好。
  问题2,下面两种写法,在性能上的差异是如何的。这个问题相对算比较简单,找个时间自己测试一下。

this.state == 5 || this.state == 9 || this.state == 0 ? true : false;
[5, 9, 0].indexOf(this.state) != -1?true : false;

后续其他优化

在翻ES6文档时,发现要交换两个数的值可以用:

[a, b] = [b, a]

可以把compare()中交换的代码做一下改进。

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