列表渲染
v-for事实上跟for循环的逻辑类似,遍历数组、对象、字符串、固定数值,遍历所给的参数也是不一样的
数组=(obj, index)
对象=(value, key)
字符串=(char, index)
固定数值(number, index)
这里面的:key原则上是必须要设置的,一般设置为index(key),如果不设置vue不会报错,但是在react会报错。
<div id="testBox">
<ul>
<!--这里in变成of也可以-->
<!--遍历数组-->
<li v-for="(p,index) in persons" :key="index">
{{p.name}}:{{p.age}}-{{index}}
</li><br />
<!--遍历对象-->
<li v-for="(value,key_index) in person" :key="key_index">
{{value}}-{{key_index}}
</li><br />
<!--遍历字符串-->
<li v-for="(char,index) in str" :key="index">
{{char}}-{{index}}
</li><br />
<!--遍历数字-->
<li v-for="(number,index) in 5" :key="index">
{{number}}-{{index}}
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#testBox',
data:{
persons:[
{name:'野原新之助', age: '6岁'},
{name:'野原广志', age: '35岁'},
{name:'野原美伢', age: '29岁'}
],
person: {
name: '野原新之助',
age: '6岁',
hobby: '喜欢漂亮的大姐姐'
},
str: '野原新之助'
}
})
</script>
key的原理
简单来说,key的作用就是在虚拟DOM对比算法的时候对比的关键字段。
实际上当用index作为key的情况,只要不打乱index,就不会出现问题,一旦打乱:
1.有输入类表单元素,每个元素的index发生改变,key从而发生改变,就形成了一连串的错位对比。
2.没有输入类表单元素。会造成不必要的真实Dom更新,影响效率(当key对应上的时候,事实上会直接用之前的真实Dom进行使用)。
所以当要打乱index顺序的时候,直接用事先设置好的id(后端数据库会有)
3.因此用id不会出错的原因是,id与数据是绑定在一起的,不管怎么样都不会形成错位对比。
4.如果只是展示作用的,用index也没问题(就是不会有类似按钮之类的添加元素)。
以用index为key做例子(用唯一id的情况跟这个类似)
<div id="testBox">
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}:{{p.age}}-<input type="text">
</li><br />
<button @click.once="addPeople">加个人</button>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#testBox',
data:{
persons:[
{id:'001', name:'野原新之助', age: '6岁'},
{id:'002', name:'野原广志', age: '35岁'},
{id:'003', name:'野原美伢', age: '29岁'}
],
},
methods: {
addPeople() {
const newObj = {id:'004', name:'卖间久里代', age: 'unKnown'};
this.persons.unshift(newObj);
}
},
})
</script>
对于没有用key的情况,vue默认用index作为它的key。
列表过滤 watch实现
<div id="testBox">
<ul>
<!-- 表单的双向绑定用v-model -->
<input type="text" v-model="keyword">
<li v-for="(p,index) in newPersons" :key="index">
{{p.name}}:{{p.age}}
</li><br />
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#testBox',
data:{
keyword:'',
persons:[
{id:'001', name:'野原新之助', age: '6岁'},
{id:'002', name:'野原广志', age: '35岁'},
{id:'003', name:'广场舞', age: '29岁'},
{id:'003', name:'舞蹈', age: '29岁'}
],
//使用空数组接收新数据,避免改变原数据使搜索内容越来越少
newPersons:[]
},
watch:{
keyword:{
/*默认一进去就执行handler,也就是在没
输入的时候就调一次,让旧数组的内容给新数组*/
immediate: true,
handler(value) {
/*filter实现过滤功能,但是不改变原数据,
而是产生新数据,所以需要接收*/
this.newPersons = this.persons.filter((p)=>{
/*index用来判断里面有没有相应的内容
有的话返回索引值,没有的话返回-1*/
return p.name.indexOf(value) !== -1;
})
}
}
}
})
</script>
<div id="testBox">
<ul>
<input type="text" v-model="keyWord">
<!-- 这里计算属性得用到,不然就没效果了 -->
<li v-for="(p,index) in filFun" :key="index">
{{p.name}}:{{p.age}}
</li><br />
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#testBox',
data:{
keyWord:'',
persons:[
{id:'001', name:'野原新之助', age: '6岁'},
{id:'002', name:'野原广志', age: '35岁'},
{id:'003', name:'广场舞', age: '29岁'},
{id:'003', name:'舞蹈', age: '29岁'}
]
},
computed: {
filFun() {
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
}
}
})
</script>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)