0 前言
在 Vue学习笔记17:纯JavaScript和Vue分实现统计输出用户输入信息及重复次数(下)_PurpleEndurer@5lcto的技术博客_51CTO博客 中,我们尝试使用Vue来实现统计输出用户输入信息及重复次数,出现的问题是所显示的输入信息列表并不是按输入先后的顺序来排列的,效果不是很理想,现在我们来做进一步修改。
1 思路
出现所显示的输入信息列表并不是按输入先后的顺序来排列这个问题的原因是,数组aRec的元素并不是按用户输入信息的顺序来存储的,而v-for指令是从头到尾的顺序把数组中的元素逐个输出的。
那么解决起来有两种思路,我们先研究第一种思路。
第一种思路是:
像之前一样,将用户本次输入的信息以及重复次数两项信息追加到数组aRec的末尾,不管数组中是否存在相同的信息。
这样数组元素的存储顺序就和用户输入信息的顺序一致了。
我们改用对象数组来实现。
aRec数组元素包括两个属性:
将数组aRec元素类型改为对象,每个对象包括两个属性:
属性sMsg:存储用户输入的一条信息
属性iTimes:存储这条信息的重复次数
即:
其中重复次数属性iTimes的值的计算 ,我们需要从数组尾部开始检索,如果发现有相同的信息,就把找到的信息中的重复次数+1后作为本次输入信息的重复次数保存起来,如果没有找到相同的信息,那么本次输入信息的重复次数值就是0。
为什么是从数组尾部而不是首部开始检索呢?
因为数组存储的信息是按用户输入信息的先后顺序来存储的,如果用户输入了重复的信息,那么最后的重复次数是储存在用户最后输入那条信息里的。
比如,用户在前5次输入的信息依次是:
- abc
- a
- abc
- b
- abc
那么这些信息在数组aRec中是这样存储的:
当用户第6次输入的信息仍然是abc时,如果从数组头部开始查找,得到的重复次数将是0。
如果是从数组尾部开始查找,得到的重复次数将是2+1。
2 改造代码
我们以 Vue学习笔记17:纯JavaScript和Vue分实现统计输出用户输入信息及重复次数(下)_PurpleEndurer@5lcto的技术博客_51CTO博客 中的最终代码【代码4.4.3】:
<script setup>
import { ref } from 'vue'
var spanMsg = ref("");
var aRec = ref([]);
var c = ref(0);//用户输入信息次数
function onClick()
{
c.value++;//用户输入信息次数+1
var r = -1; //记录本次输入信息在数组aRec中的行坐标值 ,初始值为-1
for (var i=0; i<aRec.value.length && r==-1; i++)
{
r = (aRec.value[i][0] ==spanMsg.value ? i : -1);
}
if (r==-1)
{
aRec.value.push([spanMsg.value, 0, c.value]);//追加到数组末尾
}
else
{
aRec.value[r][1]++; //重复次数+1
aRec.value[r][2] = c.value;//把本次输入信息的次数存到第3个元素
}
} //onClick()
</script>
<template>
<p style="font-size:18pt; font-weight:bold;">
使用Vue指令实现统计输出用户输入信息及重复次数
</p>
<p style="margin-left:20%; color:purple; font-weight:bold;">
by PurpleEndurer
</p>
<p>请输入信息:
<input type="text" v-model="spanMsg" placeholder="请输入信息" />
<input type="button" value="确定" @click="onClick" />
</p>
<div v-for="(v, i) in aRec">
<p>
第{{ v[2] }}次输入:{{ v[0] }}
<span v-if="v[1] > 0" >(重复 {{ v[1] }} 次)</span>
</p>
</div>
</template>
为基础进行修改。
2.1 改造JavaScript脚本代码
2.2.1 删除变量c的定义语句
即:
var c = ref(0);//用户输入信息次数
变量c是用来存储用户输入信息次数的。
因为数组aRec现在把用户输入的信息依次存储,我们可以从aRec的元素个数来算出用户输入信息次数,所以不再需要变量c了。
2.2.2 修改onClick函数
为了便于对比,我们把函数体内的原来的代码里的
c.value++;//用户输入信息次数+1
删除,把余下的代码加上注释,并在相应代码行下增加对应的新代码:
function onClick()
{
var r = -1; //记录本次输入信息在数组aRec中的行坐标值 ,初始值为-1
//从数组头部向尾部查找
//for (var i=0; i<aRec.value.length && r==-1; i++)
//从数组尾部向头部查找
for (var i = aRec.value.length-1;i>=0 && r==-1; i--)
{
//r = (aRec.value[i][0] ==spanMsg.value ? i : -1);
r = (aRec.value[i].sMsg ==spanMsg.value ? i : -1);
}
/*
if (r==-1)
{
aRec.value.push([spanMsg.value, 0, c.value]);//追加到数组末尾
}
else
{
aRec.value[r][1]++; //重复次数+1
aRec.value[r][2] = c.value;//把本次输入信息的次数存到第3个元素
}
*/
aRec.value.push({sMsg:spanMsg.value, iTimes:(r==-1 ? 0 : aRec.value[r].iTimes+1)});//追加到数组末尾
} //onClick()
因为我们要从数组 aRec尾部开始搜索,所以for语句要相应修改。
for语句的初始表达式从:
var i=0
改为
var i = aRec.value.length-1
其中 aRec.value.length-1 是数组最末一个对象元素的索引。
循环条件表达式从
i<aRec.value.length && r==-1
改为
i>=0 && r==-1
只要代表数组索引的变量i的值>=0 并且 r的值等于-1时进行循环。
循环结束以后,我们直接把用户本次输入的信息追加到数组末尾:
aRec.value.push({sMsg:spanMsg.value, iTimes:(r==-1 ? 0 : aRec.value[r].iTimes+1)});//追加到数组末尾
其中iTime属性的值要根据变量r的值来计算。
如果r的值为-1,说明在数组aRec中没有找到与用户本次输入信息相同的信息,那么iTime属性的值设为0即可。
如果r的值不为-1,说明在数组aRec中找到了与用户本次输入信息相同的信息,那么iTime属性的值设为找到的信息对象的iTime属性的值+1。
2.2 改造网页元素描述代码
2.2.1 修改技术说明代码
将
<p style="font-size:18pt; font-weight:bold;">
使用Vue指令实现统计输出用户输入信息及重复次数
</p>
改为
<p style="font-size:18pt; font-weight:bold;">
使用Vue指令及对象数组实现统计输出<br />
用户输入信息及重复次数
</p>
2.2.2 修改用户输入信息的显示代码
我们将<P></P>内的代码加上注释,并加入新的语句。
即:
<div v-for="(v, i) in aRec">
<p>
第{{ v[2] }}次输入:{{ v[0] }}
<span v-if="v[1] > 0" >(重复 {{ v[1] }} 次)</span>
</p>
</div>
改为:
<div v-for="(v, i) in aRec">
<p>
<!--
第{{ v[2] }}次输入:{{ v[0] }}
<span v-if="v[1] > 0" >(重复 {{ v[1] }} 次)</span>
//-->
第{{ i+1 }}次输入:{{ v.sMsg }}
<span v-if="v.iTimes > 0" >(重复 {{ v.iTimes }} 次)</span>
</p>
</div>
使用对象的属性比直接使用数组索引,可读性更强,也便于维护。
3 最终代码
综合以上修改后的最终代码如下【代码3】:
<script setup>
import { ref } from 'vue'
var spanMsg = ref("");
//var aRec = ref([{"sMsg":'', "iTimes":0}]);
var aRec = ref([]);
//var c = ref(0);//用户输入信息次数
function onClick()
{
//c.value++;//用户输入信息次数+1
var r = -1; //记录本次输入信息在数组aRec中的行坐标值 ,初始值为-1
//for (var i=0; i<aRec.value.length && r==-1; i++)
for (var i = aRec.value.length-1;i>=0 && r==-1; i--)
{
//r = (aRec.value[i][0] ==spanMsg.value ? i : -1);
r = (aRec.value[i].sMsg ==spanMsg.value ? i : -1);
}
/*
if (r==-1)
{
aRec.value.push([spanMsg.value, 0, c.value]);//追加到数组末尾
}
else
{
aRec.value[r][1]++; //重复次数+1
aRec.value[r][2] = c.value;//把本次输入信息的次数存到第3个元素
}
*/
aRec.value.push({sMsg:spanMsg.value, iTimes:(r==-1 ? 0 : aRec.value[r].iTimes+1)});//追加到数组末尾
} //onClick()
</script>
<template>
<p style="font-size:18pt; font-weight:bold;">
使用Vue指令及对象数组实现统计输出<br />
用户输入信息及重复次数
</p>
<p style="margin-left:20%; color:purple; font-weight:bold;">
by PurpleEndurer
</p>
<p>请输入信息:
<input type="text" v-model="spanMsg" placeholder="请输入信息" />
<input type="button" value="确定" @click="onClick" />
</p>
<div v-for="(v, i) in aRec">
<p>
<!--
第{{ v[2] }}次输入:{{ v[0] }}
<span v-if="v[1] > 0" >(重复 {{ v[1] }} 次)</span>
//-->
第{{ i+1 }}次输入:{{ v.sMsg }}
<span v-if="v.iTimes > 0" >(重复 {{ v.iTimes }} 次)</span>
</p>
</div>
</template>
4 代码运行效果
5 小结
通过使用对象数组,并修改用户输入信息存储方式,以及对数组元素的检索,我们解决了之前存在的显示的输入信息列表并不是按输入先后的顺序来排列的问题,代价就是要多使用一些存储空间。