Vue--列表


列表渲染

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>

请添加图片描述
请添加图片描述

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>

注意:
排序内容如果是混合字段,包括数字和字符串,会排不了。

请添加图片描述
请添加图片描述


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值