需求描述
在前端页面实现:根据输入的关键词,筛选指定数据等于关键词的数据行,并更新表格
直接看总结
基本思路
- 在输入框中绑定input变量
- 根据input值过滤原始数组;input为空则返回原始数组的副本;通过lodash插件实现防抖
- 将得到的新数组赋予表格绑定的model对象
方式 1——绑定按钮事件
思路描述:将步骤2封装成查询方法,并将input作为参数传入,然后绑定到按钮的点击事件
JS 实现:
data() {
return {
input: "", // 实时关键词
oldInput: "", // 上一次使用筛选功能时的关键词
origData: [], // 保存请求到的原始数据
tableData: [], // 表格展示的数据
};
},
created() {
this.setOrigData();
this.setTableData(this.origData); // 第一次加载时需手动添加表格数据
},
methods: {
// 获取服务端数据并将原始数据保存副本
setOrigTableData() {
this.origData = getServerData();
},
// 设置表格model
setTableData(data) {
this.tableData = data;
},
// 定义输入处理,并设置防抖功能
handleInput: _.debounce(function (newInput) {
this.queryData(newInput);
}, 500),
// 前端查询,筛选符合条件的原始数据并更新表格model,清空关键词时复制上一次请求服务端返回的数据副本
queryData(newInput) {
if (this.oldInput !== newInput) { // 关键词变化时才重新筛选
this.oldInput = newInput; // 保存本次的关键词
if (!this.origData) this.setOrigData(); // 原始数据不存在时重新请求
if (newInput) {
this.setTableData(
this.origData.filter(row => row.val === newInput && row)
);
} else {
this.setTableData(JSON.parse(JSON.stringify(this.origData)));
}
//} else {
// console.log("不需要修改表格数据");
//}
},
}
优点:可以设置防抖或节流
缺点:表格第一次加载时,必须手动添加表格数据;代码量太大
评价:比较传统的处理方式,对全部过程都能把握,可控性较强;小改进,将方法绑定到输入框的input事件,输入后自动筛选,可以简化用户操作
方式2——watch侦听关键词变化
思路:基本思路与方式2相同,区别是将事件绑定替换为使用watch侦听input的变化,并自动调用查询方法
JS 实现:
data() {
return {
input: "", // 实时关键词
origData: [], // 保存请求到的原始数据
tableData: [], // 表格展示的数据
};
},
created() {
this.setOrigData();
this.setTableData(this.origData); // 第一次加载时需手动添加表格数据
},
watch: {
input(val) {
this.handleInput(val);
},
},
methods: {
// 获取服务端数据并将原始数据保存副本
setOrigTableData() {
this.origData = getServerData();
},
// 设置表格model
setTableData(data) {
this.tableData = data;
},
// 定义输入处理,并设置防抖功能
handleInput: _.debounce(function (newInput) {
this.queryData(newInput);
}, 500),
// 前端查询,筛选符合条件的原始数据并更新表格model,清空关键词时复制上一次请求服务端返回的数据副本
queryData(newInput) {
if (!this.origData) this.setOrigData(); // 原始数据不存在时重新请求
if (newInput) {
this.setTableData(
this.origData.filter(row => row.val === newInput && row)
);
} else {
this.setTableData(JSON.parse(JSON.stringify(this.origData)));
}
},
}
优点:关键词变化后自动执行,不需要判断是否发生改变;可以设置防抖或节流
缺点:表格第一次加载时,必须手动添加表格数据;代码量还是较大
方式3——computed属性
思路:通过创建computed属性,自动更新tableData
JS 实现:
data() {
return {
input: "", // 实时关键词
origData: [], // 保存请求到的原始数据
};
},
computed: {
tableData() { // 表格展示的数据
if (this.input) { // 关键词非空,执行筛选
return this.origData.filter(row => row.val === this.input && row)
} else { // 关键词为空,显示原始数据
return JSON.parse(JSON.stringify(this.origData));
}
},
},
created() {
this.setOrigData();
},
methods: {
// 获取服务端数据并将原始数据保存副本
setOrigTableData() {
this.origData = getServerData();
},
}
优点:响应式自动筛选或者重新显示全部原始数据,实现代码少;表格首次加载不需要手动绑定数据,计算属性会自动更新
缺点:无法设置防抖或节流
评价:计算属性的作用是根据依赖属性响应式地更新指定属性,因此,依赖属性的每次更新都会自动触发计算属性的更新,如果设置防抖,由于计算过程是异步进行的,无法同步获取计算结果;而若是使用Promise封装防抖功能,则相当于依赖属性的每次更新都会自动生成一个新的Promise对象,使得原本的防抖功能失效
总结
- 绑定事件的实现思路最直接,也因此代码量最多,需要实现对所有过程的控制
- 通过watch侦听可以省去部分判断逻辑,代码量相对较少;适用于侦听系统或组件的状态变化,并作出反应,只适合侦听仅有单个依赖属性的场景,多依赖的场景请使用计算属性
- Vue原生的计算属性无法设置防抖或节流,要实现防抖功能请使用watch代替;适用于响应式更新存在依赖关系的属性,尤其适合依赖项多的场景,比如官方示例的firstName、familyName和fullName,fullName依赖前两项,此时使用计算属性更方便且依赖关系清晰