今天开始学习前端最流行的框架之一:vue.js,之前大概看过一些AngularJS的文章,但没有仔细学习过一个框架,所以这应该是我学习的第一个前端框架。好记性不如烂笔头,在此写一些学习笔记,以记录学习过程。
对我来说,学习一个东西的方式是在使用过程中慢慢了解熟悉它,在看了vue官方文档的安装和起步两个章节后,我打算先写一个小demo熟悉一下学习到的简单语法,就是一个todo list.
这个todo list的主要功能是添加,删除todo事项,以及事项的完成和撤销完成,并使用localStorage
在客户端存储数据。图如下:
写完之后,我发现一个问题,就是当我点击列表第一项的checkbox
表示完成这项todo时,下一项的checkbox
被自动选中(此时原来的第一项已经移动到已完成列表,这一项变成第一项),我觉得很奇怪,测试了一番又发现,在已完成列表中取消完成也会有这种情况,总之点击之后checkbox
的选中情况有点错乱。
找bug过程就不说了,也许应当先多阅读阅读官方文档再下手写的。
部分代码如下:
<li v-for="item in unFinishedList">
<input type="checkbox" v-on:click="toggleFinish(item)">
<p v-text="item.label"></p>
<span v-on:click="deleteItem(item)">X</span>
</li>
computed:{
unFinishedList:function(){
return this.items.filter(function(item){
return !item.isFinished;
})
}
}
问题就出v-for
的渲染上,官方文档上有这么一段话:
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
这个默认的模式是有效的,但是只适用于不依赖子组件状态或临时 DOM 状态(例如:表单输入值)的列表渲染输出。
因为 “就地复用” 策略,所以更新渲染todo列表时,第一个checkbox仍然是选中的。
解决方法有两个,一个是为每个li
添加key,文档中还有这么一段话:
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
这是一个解决方法,但不是最好最有效的,文档又说:
建议尽可能使用 v-for 来提供 key ,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来获得性能提升。
因为这个demo比较简单,所以其实不必要设key,还有一种方法就是todo事项的事件不一定要用v-on:click
,我在checkbox
的点击上用的是v-on:click="toggleFinish(item)
来切换状态,但其实大可不必如此,只要设置v-model="item.isFinished"
就可以达到同样的效果。
对比一下还是第二种方法比较好,因为文档只看了起步,所以写的时候没考虑到用这个,直接用了click事件。不过了解一下v-for
渲染时的“就地复用”策略也是好的。
PS:第一次写博客,可能比较啰嗦,因为发现记性不好使了,一个坑反复跳,过几个星期就忘了,所以打算写一写,可能没有什么干货,权当做笔记了,如果有写的不对的地方,还望路过的大神指点一二,感谢!