Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)

以下文章将解读并展示如何使用Vue属性监听和计算属性的方法,实现一个列表过滤。

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第1张图片

 

 1、首先看下最终要实现的效果

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第2张图片 最终实现的过滤和排序效果GIF图

2、过滤实现代码




    
    列表过滤01
    
    
    
    
    
    
    
    



    
{{index+1}} {{person.name}} {{person.sex}} {{person.age}}

3、思路解析及代码实现

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第3张图片

要实现如上图所示的效果,大致可以分为两步:

  • 第一步是获取文本框中的值。
  • 第二步是使用文本框中的值去匹配过滤已有的数据源。

一开始,我自己的思路是通过键盘事件来获取input中的输入值的,比如keydown,这么做可能能够实现获取input值的目标,无论按下什么键都会触发,这似乎不符合预期;真实的预期是:当input中的值产生变化的时候,才需要新的值,然后根据新的值去进行过滤。

既是input标签,而且需要获取变化的值,v-model应该比较合适。于是就有了如下的代码:

使用v-model绑定input中的value与Vue实例keyword属性,这样视图变化,属性keyword属性数据也会变化。

与此同时,使用属性监听,来监听keyword值的变化,就有了如下的代码:

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第4张图片

以上的代码确实实现了列表过滤的功能,可是也出现了一些问题,如下:就是每命中检索过滤一次,persons源数据就会变少,直至最后persons中无一条数据。我们希望每次都是从persons源数据中去匹配过滤,优化的代码如下:



    
{{index+1}} {{person.name}} {{person.sex}} {{person.age}}

 两个地方的变化,一是给Vue实例新增了一个属性filterPersons,用于放置每次命中过滤的数据。

data:{
  keyword:'',
    persons:[
    {id:'001', name:'马冬梅', sex:'女', age:18},
    {id:'002', name:'周冬雨', sex:'女', age:19},
    {id:'003', name:'周杰伦', sex:'男', age:20},
    {id:'004', name:'温兆伦', sex:'男', age:40},
  ],
    filterPersons:[]
}

二是v-for循环的数据源的变化,变为新增的那个属性filterPersons,这样每次展示的就是命中的数据。


  {{index+1}}
  {{person.name}}
  {{person.sex}}
  {{person.age}}

但如此仍然出现了一些问题,如下:

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第5张图片

就是初始化的时候,看不到文本框下可供检索的对象列表,这个也不是所预期的,经过优化的代码如下:

不适用属性监听的简写形式,而是采用原始的写法,并添加上了immediate:true的配置,表示初始化的时候就执行一次监听,如此就可以实现本文开头所需要的效果:

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第6张图片

4、解读handler里的代码

紧接着上述内容,为什么让监听方法handler在初始化的时候就可以展示所有的可检索项?主要是因为indexOf这个方法。

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第7张图片

通过测试我们可知,indexOf这个方法可以找出对应字符在字符串中的索引位置,如果找不到则返回“-1”,找到了则返回字符在对应位置上的索引。

有一个特别的字符就是空字符串,如果是空字符串,那么返回的也是“0”,跟字符串中首个字符返回的值是一样的,都是“0”。

watch:{
  keyword:{
    immediate:true,
      handler(newValue){
      this.filterPersons = this.persons.filter((person)=>{
        return person.name.indexOf(newValue) !== -1;
      })
    }
  }
}

所以在以上代码中,当设置immediate:true的时候,就是初始化的时候,使用空字符串进行一次匹配,因为返回的结果是“0”,其不等于“-1”,结果为true,所以返回了所有源数据persons的数据给filterPersons,就可以看见input下展示的所有源数据。

真是妙不可言呐!!!

5、使用计算属性实现




    
    列表过滤-计算属性实现01
    
    
    
    
    
    
    
    



    
{{index+1}} {{person.name}} {{person.sex}} {{person.age}}

计算属性依赖Vue实例data中的属性数据,当keyword的发生改变的时候,filterPersons这个计算属性就会重新再计算一次,相比属性监听,不需要再额外新增和维护属性filterPersons,并且也无需单独监听keyword属性。

当计算属性和监听属性都能实现的时候,我们优先选择计算属性的方式去实现。

6、列表排序

需要实现如下的升降序的效果:

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第8张图片

效果分析:应该是对已经查询到的数据进行排序,而不是对源数据。比如:通过“冬”查询到了马冬梅和周冬雨两个人,此时如果点击年龄升序,则,年龄最小的在前,年龄最大的在后。

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第9张图片

而如果是通过“伦”搜索到温兆伦和周杰伦,此时如果是年龄降序,则温兆伦在最前面,而周杰伦在最后面,如下图所示:

Vue列表过滤(过滤|排序不分家)-尚硅谷张天禹(笔记)_第10张图片 最终实现的过滤和排序效果GIF图

过滤排序实现的代码实现如下:




    
    列表过滤-计算属性实现01
    
    
    
    
    
    
    
    



    

{{index+1}} {{person.name}} {{person.sex}} {{person.age}}

你可能感兴趣的:(Vue,vue.js,javascript,前端,html)