vue-java-tutorials/vue2-tutorials/import-script/11-列表过滤.md

169 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Vue2 列表过滤与排序综合文档
## 一、功能概述
本示例展示了 Vue2 中如何实现列表的实时过滤与动态排序功能,结合计算属性实现了高效的数据处理。
## 二、代码实现解析
```html
<div id="app">
<h1>列表过滤</h1>
<!-- 搜索框 -->
<input type="text" v-model="keyword">
<!-- 排序按钮 -->
<button @click="sortType = 2">年龄升序</button>
<button @click="sortType = 1">年龄降序</button>
<button @click="sortType = 0">重置</button>
<!-- 结果列表 -->
<ul>
<li v-for="(item,index) in filterPersion" :key="item.id">
{{item.name}}---{{item.age}}---{{item.sex}}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
sortType: 0, // 0-默认 1-降序 2-升序
keyword: "", // 搜索关键词
list: [
{ id: "001", name: "Bunny-001", age: 19, sex: "男" },
{ id: "002", name: "Bunny-002", age: 16, sex: "男" },
// ...其他数据
]
},
computed: {
filterPersion() {
// 1. 过滤
let newList = this.list.filter(person =>
person.name.includes(this.keyword)
);
// 2. 排序
if (this.sortType !== 0) {
newList.sort((a, b) =>
this.sortType === 2 ? a.age - b.age : b.age - a.age
);
}
return newList;
}
}
});
</script>
```
## 三、核心机制详解
### 1. 数据流设计
```
原始数据 (list)
[过滤] → 根据 keyword 筛选
[排序] → 根据 sortType 排序 (可选)
渲染列表 (filterPersion)
```
### 2. 计算属性优势
- **自动缓存**:依赖项未变化时不重新计算
- **响应式**keyword 或 sortType 变化自动更新
- **声明式**:模板保持简洁,逻辑集中管理
### 3. 排序算法优化
```javascript
// 三元运算符实现升降序切换
(a, b) => this.sortType === 2 ? a.age - b.age : b.age - a.age
```
## 四、最佳实践建议
### 1. 性能优化
- **避免深拷贝**:直接操作过滤后的数组
- **防抖处理**:搜索框添加防抖(使用 lodash.debounce
- **分页加载**:大数据集应配合分页
### 2. 代码改进
```javascript
// 更安全的字符串包含检查
person.name.toLowerCase().includes(this.keyword.toLowerCase())
// 可配置的排序函数
const sortStrategies = {
1: (a, b) => b.age - a.age,
2: (a, b) => a.age - b.age
};
newList.sort(sortStrategies[this.sortType]);
```
### 3. Key 的使用
```html
<!-- 使用唯一id而非index作为key -->
<li v-for="item in filterPersion" :key="item.id">
```
## 五、扩展功能实现
### 1. 多条件过滤
```javascript
filterPersion() {
return this.list.filter(person => {
const nameMatch = person.name.includes(this.keyword);
const ageMatch = this.filterAge === '' || person.age == this.filterAge;
return nameMatch && ageMatch;
});
}
```
### 2. 多列排序
```javascript
data() {
return {
sortConfig: { field: 'age', order: 1 } // 1升序-1降序
}
},
computed: {
sortedList() {
return [...this.filteredList].sort((a, b) => {
return a[this.sortConfig.field] > b[this.sortConfig.field]
? this.sortConfig.order : -this.sortConfig.order;
});
}
}
```
### 3. 异步数据加载
```javascript
async loadData() {
this.list = await fetch('/api/persons').then(res => res.json());
}
```
## 六、常见问题解决方案
1. **列表不更新问题**
- 确保使用变异方法修改原始数组
- 或使用 `Vue.set` 更新数组元素
2. **排序状态保持**
```javascript
created() {
this.sortType = Number(localStorage.getItem('sortType')) || 0;
},
watch: {
sortType(newVal) {
localStorage.setItem('sortType', newVal);
}
}
```
3. **空搜索结果处理**
```html
<div v-if="filterPersion.length === 0">暂无匹配结果</div>
```