v-for列表过滤和排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了v-for列表过滤和排序相关的知识,希望对你有一定的参考价值。

参考技术A 1.过滤

即按关键词过滤出所需数据,这里用到了filter和indexOf方法

filter() 方法

注意:filter() 方法不会改变原数组,不会对空数组进行检测

indexOf() 方法

注意:indexOf() 方法对大小写敏感!如果要检索的字符串值没有出现,则该方法返回 -1。

这里是按用户名过滤的,绑定的字符串值是searchName,indexOf方法返回用户名出现的位置,

然后filter方法创建符合用户名的新数组

2.排序

按所需条件进行排序,不改变列表数据,这里用到了sort() 方法

这里是按年龄大小排序的,默认orderType=0,orderType=1或2对应升序降序,点击按钮时传orderType的值再进行判断。匿名一个比较函数设置参数p1,p2,升序的话返回的是小于0的值,降序返回的是大于0的值

列表渲染,key作用与原理,列表过滤,列表排序

v-for指令:

  • 用于展示列表数据
  • 语法:<li v-for="(item, index) in xxx" :key="yyy">,其中key可以是index,也可以是遍历对象的唯一标识
  • 可遍历:数组、对象、字符串(用的少)、指定次数(用的少)

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <!--    遍历列表-->
    <h2>人员列表</h2>
    <ul>
        <li v-for="p in persons" :key="p.id">p.name - p.age</li>
    </ul>

    <!--    <h2>人员列表</h2>-->
    <!--    <ul>-->
    <!--        <li v-for="(p,index) in persons" :key="index">p.name - p.age</li>-->
    <!--    </ul>-->

    <!--    <h2>人员列表</h2>-->
    <!--    <ul>-->
    <!--        <li v-for="(a,b,c) in persons">a - b &#45;&#45; c</li>-->
    <!--    </ul>-->

    <!--    遍历对象-->
    <h2>汽车信息</h2>
    <ul>
        <li v-for="(value,k) in cars" :key="k">k -- value</li>
    </ul>

    <!--    遍历字符串-->
    <h3>测试遍历字符串</h3>
    <ul>
        <li v-for="(char,index) in strs" :key="index">
            char -- index
        </li>
    </ul>

    <!--    遍历指定次数-->
    <h2>测试遍历指定次数</h2>
    <ul>
        <li v-for="(number,index) in  5">number -- index</li>
    </ul>
</div>
<script>
    Vue.config.productionTip = false
    const vm = new Vue(
        el: "#app",
        data: 
            persons: [
                id: '001', name: '张三', age: 18,
                id: '002', name: '李四', age: 19,
                id: '003', name: '王五', age: 20
            ],
            cars: 
                name: 'aodi',
                price: '18',
                color: 'balck'
            ,
            strs: 'hello'
        
    )
</script>
</body>
</html>

key作用与原理

react、vue中的key有什么作用?(key的内部原理)

虚拟DOM中key的作用:key是虚拟DOM中对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

对比规则:

旧虚拟DOM中找到了与新虚拟DOM相同的key:

若虚拟DOM中内容没变, 直接使用之前的真实DOM
若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
旧虚拟DOM中未找到与新虚拟DOM相同的key:创建新的真实DOM,随后渲染到到页面

用index作为key可能会引发的问题:

若对数据进行逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
若结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题
 

开发中如何选择key?

最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表,使用index作为key是没有问题的
 

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <h2>人员列表</h2>
    <button @click.once="add">添加老刘</button>
    <ul>
        <h3>index作为key</h3>
        <!--        index作为key-->
        <li v-for="(p,index) in persons" :key="index">
            p.name - p.age<input type="text">
        </li>
    </ul>

    <ul>
        <!--        p.id作为key-->
        <h3>p.id作为key</h3>
        <li v-for="(p,index) in persons" :key="p.id">
            p.name - p.age<input type="text">
        </li>
    </ul>
</div>
<script>
    Vue.config.productionTip = false
    const vm = new Vue(
        el: "#app",
        data: 
            persons: [
                id: '001', name: '张三', age: 18,
                id: '002', name: '李四', age: 19,
                id: '003', name: '王五', age: 20
            ]
        ,
        methods: 
            add() 
                const p = id: '004', name: '老刘', age: 40
                this.persons.unshift(p)
            
        
    )
</script>
</body>
</html>

列表过滤

方法一:使用监听属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <h2>人员列表</h2>
    <input type="text" placeholder="请输入姓名" v-model="keyWord">
    <ul>
        <li v-for="(p,index) in filpersons" :key="p.id">
            p.name - p.age - p.sex
        </li>
    </ul>
</div>
<script>
    Vue.config.productionTip = false
    const vm = new Vue(
        el: "#app",
        data: 
            keyWord: "",
            persons: [
                id: '001', name: '马冬梅', age: 19, sex: '女',
                id: '002', name: '周冬雨', age: 20, sex: '女',
                id: '003', name: '周杰伦', age: 21, sex: '男',
                id: '004', name: '温兆伦', age: 22, sex: '男'
            ],
            filpersons: []
        ,
        watch: 
            keyWord: 
                immediate: true,
                handler(newval) 
                    this.filpersons = this.persons.filter((p) => 
                        return p.name.indexOf(newval) !== -1
                    )
                
            
        
    )
</script>
</body>
</html>

方法二:使用计算属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <h2>人员列表</h2>
    <input type="text" placeholder="请输入姓名" v-model="keyWord">
    <ul>
        <li v-for="(p,index) in filpersons" :key="p.id">
            p.name - p.age - p.sex
        </li>
    </ul>
</div>
<script>
    Vue.config.productionTip = false
    const vm = new Vue(
        el: "#app",
        data: 
            keyWord: "",
            persons: [
                id: '001', name: '马冬梅', age: 19, sex: '女',
                id: '002', name: '周冬雨', age: 20, sex: '女',
                id: '003', name: '周杰伦', age: 21, sex: '男',
                id: '004', name: '温兆伦', age: 22, sex: '男'
            ],
        ,
        computed: 
            filpersons() 
                return this.persons.filter((p) => 
                    return p.name.indexOf(this.keyWord) !== -1
                )
            
        
    )
</script>
</body>
</html>

列表排序

先过滤在排序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <h2>人员列表</h2>
    <input type="text" placeholder="请输入姓名" v-model="keyWord">
    <button @click="sortType = 2">年龄升序</button>
    <button @click="sortType = 1">年龄降序</button>
    <button @click="sortType = 0">原顺序</button>
    <ul>
        <li v-for="(p,index) in filpersons" :key="p.id">
            p.name - p.age - p.sex
        </li>
    </ul>
</div>
<script>
    Vue.config.productionTip = false
    const vm = new Vue(
        el: "#app",
        data: 
            keyWord: "",
            sortType: 0,// 0原顺序  1降序 2升序
            persons: [
                id: '001', name: '马冬梅', age: 19, sex: '女',
                id: '002', name: '周冬雨', age: 20, sex: '女',
                id: '003', name: '周杰伦', age: 21, sex: '男',
                id: '004', name: '温兆伦', age: 22, sex: '男'
            ],
        ,
        computed: 
            filpersons() 
                const arr = this.persons.filter((p) => 
                    return p.name.indexOf(this.keyWord) !== -1
                )
                if (this.sortType) 
                    arr.sort((a, b) => 
                        return this.sortType === 1 ? b.age - a.age : a.age - b.age
                    )
                
                return arr
            
        
    )
</script>
</body>
</html>

以上是关于v-for列表过滤和排序的主要内容,如果未能解决你的问题,请参考以下文章

列表渲染,key作用与原理,列表过滤,列表排序

Vue.js列表渲染 v-for

v-for列表排序

Vue的v-for中列表项拖拽排序详细方法

Vue 条件渲染,列表渲染,key的作用和原理,列表过滤,列表排序,Vue监测数据原理和注意事项

从另一个排序列表创建过滤列表