先上出现的问题图(vue框架):
<div id="sortable">
<li class='gray' v-for="(item,idx) in keywords_list" :id="item.kid">
<span>{{idx + 1}}</span>
<span>{{item.kid}}</span>
</li>
</div>
data: {
keywords_list: [
{kid: 1},
{kid: 2},
{kid: 3},
{kid: 4},
{kid: 7},
{kid: 8},
]
},
现在是我要将其进行排序,这里用到了一个JQuery的一个可拖动排序插件:https://jqueryui.com/sortable/
好,这是刚开始我写的js:
sort_keywords: function(){
var result = [];
var single = {};
$("#sortable li").each(function(idx,ele){
single['kid'] = $(this).attr('id');
single['seq'] = idx;
result.push(single);
})
console.log(result);
},
在浏览器打印的是这样的:
打印出的值既然全部是一样的,很显然这是一个错误的写法。
后来经过多次分析,想了一个多小时(都怪自己基础知识不牢固,这时间花的不值啊)
刚开始,以为定义了一个空对象,每次遍历的时候把kid赋值给single对象里的属性名为kid的属性就好了,然后再把single这个对象一次一次Push进数组就可以实现了。
后来发现,只要懂for循环的同学不难看出,由于每次遍历的kid都不同,虽然第一次成功push进数组,但是在第二次遍历之后,$(this).attr('id')这个值发生了改变,且赋值给同一个对象的同一个属性!又由于对象的属性唯一性,后面的值将替换之前的值,所以,层层遍历之后,对象属性kid的值将是最后一个遍历出来的$(this).attr('id'),所以在最后数组中的元素全部是一样的。
改正之后的js:
sort_keywords: function(){
var result = [];
$("#sortable li").each(function(idx,ele){
var single = {
kid: $(this).attr('id'),
seq: idx
};
result.push(single)
})
console.log(result)
},
打印出的结果:
分析:
如果我们在内部定义一个对象,属性都已设置好,我们只需要把值赋值给属性名即可,这种方法为啥可行?是因为每次遍历的时候,都会新声明一个对象,然后传值,再push进数组。虽然这个同名对象会被后一轮遍历所替换,但是没关系啊!因为你已经把想要的值已经push进数组了呀!