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>