vue的v-model是一个非常好用的双向绑定指令,不难想象因为它帮我们简化了多少逻辑代码。但在最近,测试反馈给我一个问题:在搜索时,只填搜索内容而不点击搜索按钮,接着点击翻页,会有报错说该条件下的搜索结果不存在(就是如下的巨简单无奇的搜索框)。
这里我先说明一下我们项目的搜索和分页机制。我们项目的分页是我们在每次点击页码,将页码数字和各种搜索条件传给后端,再将后端的数据在页面展示出来。但搜索(比如searchText="张三"参数)和分页(比如page参数)其实发送的是同一个路径的接口,而且因为搜索后的结果也是要有分页的,因此不能说点击搜索后就不传name参数。因此上面提到的问题,简而言之就是:比如我搜索得出的结果只有一页,但我填写搜索条件后点击的是分页中的第二页,将page=2和searchText="张三"传给后端,自然会有报错,而且不出意外你element带的listLoading也会一直转个不停哦(如果你设置的是获取结果后取消listLoading的话)。
而这一切问题的根源,在于v-model的滥用。过度依赖于这个指令。我们之后的想法是不让它输入即赋值,而且要等他点击搜索按钮后。所以之后我修改了整个页面所有搜索的输入框和选择器。这里说明一下两者的处理方式是不同的。
<div class="tab-search">
<!-- 获取输入框的dom元素 -->
<el-input placeholder="请输入名称" ref="searchText"></el-input>
<!-- 获取选择器的dom元素 -->
<el-select ref="status" v-model="status" placeholder="请选择状态" >
<el-option v-for="item in statusType" :key="item.key" :label="item.label"
:value="item.value"></el-option>
</el-select>
<el-button @click="searchContract">搜索</el-button>
</div>
我先是将输入框中的v-model="searchText"改成了ref="name",由于element的选择器没有v-model绑定的话会报错,所以留着。我们使用一个叫statusTypeItem的中间变量将选择器中的选中的值取到,起这个名字的原因是statusType为我们选择器中的数据,类似于这种:
statusType = [
{label:'苹果',value:1},
{label:'橘子',value:2},
{label:'苹果',value:1}
]
// 搜索
searchContract() {
console.log(this.$refs.status)
this.searchText = this.$refs.searchText.currentValue // 获取searchText的值
this.statusTypeItem = this.$refs.status.value // 获取status的值
this.page = 1 // 搜索时将page置为1
const params = { //需要传给后台的参数
page_size: 15,
page: this.page,
project_name: this.searchText,
status: this.statusTypeItem
}
this.getData() // 调用向后台发送请求的方法
},
这样就可以解决一开始说到的问题,只有当点击搜索后才可以赋值。