Vue:列表操作

Vue:列表操作

2.9、列表过滤

2.9.1、回顾 filter

filter 是 JavaScript 数组的一个方法,用于创建一个新数组,其中包含通过指定条件的所有元素。filter 不会破坏原数组的结构,会生成一个全新的数组。

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// filter不会破坏原数组的结构,会生成一个全新的数组。
let newArr = arr.filter((num) => {
    // return 过滤规则
    return num < 5;
});

console.log(newArr);

可以进一步拓展 filter 的使用场景,比如过滤对象数组:

let users = [
    { id: 1, name: 'Alice', age: 25 },
    { id: 2, name: 'Bob', age: 30 },
    { id: 3, name: 'Charlie', age: 20 }
];

let youngUsers = users.filter(user => user.age < 25);
console.log(youngUsers);

2.9.2、列表过滤 watch 属性实现

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" placeholder="请输入搜索关键字" v-model="keyword" />
        <table>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>薪资</th>
                <th>选择</th>
            </tr>
            <tr v-for="(hero, index) in filteredHeros" :key="hero.id">
                <td>{{index + 1}}</td>
                <td>{{hero.name}}</td>
                <td>{{hero.power}}</td>
                <td><input type="checkbox" /></td>
            </tr>
        </table>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                keyword: "",
                msg: "列表过滤",
                heros: [
                    { id: "101", name: "章三", power: 10000 },
                    { id: "102", name: "三响", power: 9000 },
                    { id: "103", name: "李四", power: 8000 },
                    { id: "104", name: "李章", power: 6000 },
                ],
                filteredHeros: [],
            },
            watch: {
                // 简写形式
                // 有bug,无法一开始就检测(并没有初始化执行生成渲染页面数据)
                /* keyword(val){
                    // 执行过滤规则
                    this.filteredHeros = this.heros.filter((hero) => {
                        return hero.name.indexOf(val) >= 0
                    })
                } */
                // 使用完整形式
                keyword: {
                    immediate: true,
                    handler(val) {
                        this.filteredHeros = this.heros.filter((hero) => {
                            return hero.name.indexOf(val) >= 0;
                        });
                    },
                },
            },
        });
    </script>
</body>

可以添加一些错误处理和提示信息,当没有匹配结果时显示提示:

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" placeholder="请输入搜索关键字" v-model="keyword" />
        <table>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>薪资</th>
                <th>选择</th>
            </tr>
            <tr v-for="(hero, index) in filteredHeros" :key="hero.id">
                <td>{{index + 1}}</td>
                <td>{{hero.name}}</td>
                <td>{{hero.power}}</td>
                <td><input type="checkbox" /></td>
            </tr>
        </table>
        <p v-if="filteredHeros.length === 0 && keyword!== ''">没有找到匹配的结果。</p>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                keyword: "",
                msg: "列表过滤",
                heros: [
                    { id: "101", name: "章三", power: 10000 },
                    { id: "102", name: "三响", power: 9000 },
                    { id: "103", name: "李四", power: 8000 },
                    { id: "104", name: "李章", power: 6000 },
                ],
                filteredHeros: [],
            },
            watch: {
                keyword: {
                    immediate: true,
                    handler(val) {
                        this.filteredHeros = this.heros.filter((hero) => {
                            return hero.name.indexOf(val) >= 0;
                        });
                    },
                },
            },
        });
    </script>
</body>

2.9.3、列表过滤 computed 属性实现

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" placeholder="请输入搜索关键字" v-model="keyword" />
        <table>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>薪资</th>
                <th>选择</th>
            </tr>
            <tr v-for="(hero, index) in filteredHeros" :key="hero.id">
                <td>{{index + 1}}</td>
                <td>{{hero.name}}</td>
                <td>{{hero.power}}</td>
                <td><input type="checkbox" /></td>
            </tr>
        </table>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                keyword: "",
                msg: "列表过滤",
                heros: [
                    { id: "101", name: "章三", power: 10000 },
                    { id: "102", name: "三响", power: 9000 },
                    { id: "103", name: "李四", power: 8000 },
                    { id: "104", name: "李章", power: 11000 },
                ],
            },
            computed: {
                filteredHeros() {
                    // 执行过滤
                    return this.heros.filter((hero) => {
                        return hero.name.indexOf(this.keyword) >= 0;
                    });
                },
            },
        });
    </script>
</body>

可以将过滤逻辑封装成一个独立的方法,提高代码的可维护性:

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" placeholder="请输入搜索关键字" v-model="keyword" />
        <table>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>薪资</th>
                <th>选择</th>
            </tr>
            <tr v-for="(hero, index) in filteredHeros" :key="hero.id">
                <td>{{index + 1}}</td>
                <td>{{hero.name}}</td>
                <td>{{hero.power}}</td>
                <td><input type="checkbox" /></td>
            </tr>
        </table>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                keyword: "",
                msg: "列表过滤",
                heros: [
                    { id: "101", name: "章三", power: 10000 },
                    { id: "102", name: "三响", power: 9000 },
                    { id: "103", name: "李四", power: 8000 },
                    { id: "104", name: "李章", power: 11000 },
                ],
            },
            computed: {
                filteredHeros() {
                    return this.filterHeros(this.keyword);
                },
            },
            methods: {
                filterHeros(keyword) {
                    return this.heros.filter((hero) => {
                        return hero.name.indexOf(keyword) >= 0;
                    });
                },
            },
        });
    </script>
</body>

2.10、列表排序

2.10.1、回顾 sort 方法

sort 方法用于对数组的元素进行排序。sort 方法排序之后,不会生成一个新的数组,是在原数组的基础之上进行排序,会影响原数组的结构。

// 回顾sort方法
let arr = [8, 9, 5, 4, 1, 2, 3];

// sort方法排序之后,不会生成一个新的数组,是在原数组的基础之上进行排序,会影响原数组的结构。
arr.sort((a, b) => {
    // a在前,升序,b在前降序
    return b - a;
});

console.log(arr);

可以拓展 sort 方法对对象数组进行排序,比如按对象的某个属性排序:

let students = [
    { name: 'Alice', score: 85 },
    { name: 'Bob', score: 90 },
    { name: 'Charlie', score: 78 }
];

students.sort((a, b) => a.score - b.score);
console.log(students);

2.10.2、列表排序

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" placeholder="请输入搜索关键字" v-model="keyword" />
        <br />
        <button @click="type = 1">升序</button>
        <button @click="type = 2">降序</button>
        <button @click="type = 0">原序</button>
        <table>
            <tr>
                <th>序号</th>
                <th>英雄</th>
                <th>能量值</th>
                <th>选择</th>
            </tr>
            <tr v-for="(hero, index) in filteredHeros" :key="hero.id">
                <td>{{index + 1}}</td>
                <td>{{hero.name}}</td>
                <td>{{hero.power}}</td>
                <td><input type="checkbox" /></td>
            </tr>
        </table>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                // 定义标识项,1是升序,2是降序,0是原序
                type: 0,
                keyword: "",
                msg: "列表排序",
                heros: [
                    { id: "101", name: "章三", power: 10000 },
                    { id: "102", name: "三响", power: 9000 },
                    { id: "103", name: "李四", power: 8000 },
                    { id: "104", name: "李章", power: 11000 },
                ],
            },
            computed: {
                filteredHeros() {
                    // 执行过滤  拿到过滤后的数组
                    const arr = this.heros.filter((hero) => {
                        return hero.name.indexOf(this.keyword) >= 0;
                    });
                    // 排序,根据type值进行降排序
                    if (this.type === 1) {
                        arr.sort((a, b) => {
                            return a.power - b.power;
                        });
                    } else if (this.type == 2) {
                        arr.sort((a, b) => {
                            return b.power - a.power;
                        });
                    }

                    // 返回
                    return arr;
                },
            },
        });
    </script>
</body>

可以添加一个重置按钮,用于清空搜索关键字和恢复原序:

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" placeholder="请输入搜索关键字" v-model="keyword" />
        <br />
        <button @click="type = 1">升序</button>
        <button @click="type = 2">降序</button>
        <button @click="type = 0">原序</button>
        <button @click="reset">重置</button>
        <table>
            <tr>
                <th>序号</th>
                <th>英雄</th>
                <th>能量值</th>
                <th>选择</th>
            </tr>
            <tr v-for="(hero, index) in filteredHeros" :key="hero.id">
                <td>{{index + 1}}</td>
                <td>{{hero.name}}</td>
                <td>{{hero.power}}</td>
                <td><input type="checkbox" /></td>
            </tr>
        </table>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                // 定义标识项,1是升序,2是降序,0是原序
                type: 0,
                keyword: "",
                msg: "列表排序",
                heros: [
                    { id: "101", name: "章三", power: 10000 },
                    { id: "102", name: "三响", power: 9000 },
                    { id: "103", name: "李四", power: 8000 },
                    { id: "104", name: "李章", power: 11000 },
                ],
            },
            computed: {
                filteredHeros() {
                    // 执行过滤  拿到过滤后的数组
                    const arr = this.heros.filter((hero) => {
                        return hero.name.indexOf(this.keyword) >= 0;
                    });
                    // 排序,根据type值进行降排序
                    if (this.type === 1) {
                        arr.sort((a, b) => {
                            return a.power - b.power;
                        });
                    } else if (this.type == 2) {
                        arr.sort((a, b) => {
                            return b.power - a.power;
                        });
                    }

                    // 返回
                    return arr;
                },
            },
            methods: {
                reset() {
                    this.keyword = "";
                    this.type = 0;
                },
            },
        });
    </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值