列表渲染
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:{
immediate: true,
handler(value) {
this.newPersons = this.persons.filter((p)=>{
return p.name.indexOf(value) !== -1;
})
}
}
}
})
</script>
computed实现
<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>
列表排序
<div id="testBox">
<input type="text" v-model="keyWord">
<button @click="sortType = 0">原顺序</button>
<button @click="sortType = 1">正序排序</button>
<button @click="sortType = 2">逆序排序</button>
<ul>
<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:{
sortType:0,
keyWord:'',
persons:[
{id:'001', name:'野原新之助', age: '6'},
{id:'002', name:'野原广志', age: '35'},
{id:'003', name:'广场舞', age: '20'},
{id:'003', name:'舞蹈', age: '29'}
]
},
computed: {
filFun() {
const arr = this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
if(this.sortType) {
arr.sort((p1, p2)=>{
return this.sortType === 1 ? p1.age-p2.age : p2.age-p1.age;
})
}
return arr;
}
}
})
</script>
注意: 排序内容如果是混合字段,包括数字和字符串,会排不了。
|