Vue.js 自定义过滤器-阿里云开发者社区

开发者社区> 技术小牛人> 正文

Vue.js 自定义过滤器

简介:
+关注继续查看

过滤器,本质上就是一个函数。其作用在于用户输入数据后,它能够进行处理,并返回一个数据结果。


Vue.js 与 AngularJS 中的过滤器语法有些相似,使用管道符(|)进行连接,代码示例如下:

1
{{'abc' | uppercase}}    'abc' => 'ABC'


这里使用了Vue.js 内置的过滤器 uppercase,将字符串中的字母全部转换成大写形式。


Vue.js 支持在任何出现表达式的地方添加过滤器,除了上面例子中的 双大括号 表达式之外,还可以在绑定指令的表达式后调用,代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
    <span v-text="message | uppercase"></span>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            message:'hello world!'
        }
    })
</script>


渲染为: =>  HELLO WORLD!


Vue 2.x 中,过滤器只能在 mustache 绑定中使用。为了在指令绑定中实现同样的行为,你应该使用计算属性。


过滤器可以串联:

1
{{ message | filterA | filterB }}


这里可以看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
    <h1>{{'ABCDE' |lowercase | capitalize }}</h1>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            message:''
        }
    })
</script>


lowercase 过滤器:把数据变成小写形式

capitalize过滤器:把首字母变成大写形式

// 'ABCDE' -> 'abcde' -> 'Abcde'


过滤器可以接受参数,参数跟在过滤器名称后面,参数之间以空格分隔。代码示例如下:

1
{{ message | filterA('arg1', arg2) }}


过滤器函数将始终以表达式的值作为第一个参数,带引号的参数会被当作字符串处理,而不带引号的参数会被当作数据属性名来处理。


这里的 message 将作为第一个参数,字符串arg1 作为第二个参数,表达式 arg2 的值在计算出来以后作为第三个参数传给过滤器。同时,Vue.js 的过滤器支持链式调用,上一个过滤器的输出结果可以作为下一个过滤器的输入


内置过滤器

必须指出的是,在Vue2.0中,删除了所有的内置过滤器

1、字母操作

Vue.js 内置了 capitalize、uppercase、lowercase 三个过滤器用于处理英文字符。注意:这三个过滤器仅针对英文字符串使用


1-1、capitalize

capitalize 过滤器用于将表达式中的首字母转换为大写形式

1
{{'abc' | capitalize}}  // 'abc' => 'Abc'


1-2、uppercase

uppercase 过滤器用于将表达式中的所有字母转换为大写形式

1
{{'abc' | uppercase}}  // 'abc' => 'ABC'


1-3、lowercase

lowercase 过滤器用于将表达式中的所有字母转换为小写形式

1
{{'ABC' | lowercase}}  // 'ABC' => 'abc'


2、限制

Vue.js 中内置了 limitBy、filterBy、orderBy 三个过滤器用于处理并返回过滤后的数组,比如与v-for搭配使用。

注意:这三个过滤器所处理的表达式的值必须是数组,否则程序会报错


2-1、limitBy

limitBy 过滤器的作用是限制数组为开始前的 N 个元素,其中,N 由传入的第一个参数指定,表示限制几个,默认为 0, 即取全部的元素。第二个参数可选,用于指定从哪开始,比如:第一个参数是4,第二个参数是5,则表示取4个元素,从下标为5的元素开始。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
    <ul>
        <!--第二个参数不指定,即取全部,从0开始-->
        <li v-for="item in items | limitBy">`item`</li>
    </ul>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            items:[1,2,3,4,5,6,7,8,9,10]
        }
    })
</script>

wKiom1g1CeHTwSRPAAAEYlPPME4231.png

1
2
3
4
5
6
<div id="app">
    <ul>
        <!--只显示5个元素,从0开始-->
        <li v-for="item in items | limitBy 5">`item`</li>
    </ul>
</div>

wKioL1g1Ci7D7YYLAAACrj7bsKU561.png


1
2
3
4
5
6
<div id="app">
    <ul>
        <!--显示4个,从下标为3的元素开始  注意:下标是从0开始-->
        <li v-for="item in items | limitBy 4 3">`item`</li>
    </ul>
</div>

wKiom1g1Cx7jMoU9AAACTw_saNE033.png

还可以这么使用:

1
2
3
4
5
6
<div id="app">
    <ul>
        <!--取6个,从下标为4的元素开始  注意:数组的长度是arr.length -->
        <li v-for="item in items | limitBy  items.length-4 4">`item`</li>
    </ul>
</div>

wKioL1g1D9uxlQIZAAADuGuwQv4262.png

2-2、filterBy

filterBy过滤器的使用比较灵活,其第一个参数可以是字符串或者函数,过滤条件是:'string || function' + in + 'optionKeyName'


如果第一个参数是字符串,那么将在每个数组元素中搜索它,并返回包含该字符串的元素组成的数组。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app">
    <ul>
        <li v-for="val in arr | filterBy 'a'">`val`</li>
    </ul>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            arr:['pear','orange','cherry','lemon']
        }
    })
</script>

wKiom1g1EnaBWk7gAAACNcjzOkQ032.png

如果数组元素是一个对象,过滤器将递归地在它所有属性中搜索。为了缩小搜索范围,可以指定一个搜索字段。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
    <input v-model="uname">
    <ul>
        <li v-for="user in users | filterBy uname in 'uname'">`user`.`uname`</li>
    </ul>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            uname:'',
            users:[
                {uname:'Tom'},
                {uname:'Jerry'},
                {uname:'Kobe'},
                {uname:'James'}
            ]
        }
    })
</script>

wKioL1g1FQKRNt6DAAAEXizhf1w010.png wKiom1g1FQ6jblBaAAAD3aabaZI998.png

如果 filterBy 的第一个参数是函数,则过滤器将根据函数的返回结果进行过滤。此时 filterBy过滤器将调用 Javascript 数组中内置的函数 filter() 对数组进行处理,待过滤数组中的每个元素都将作为参数输入并执行传入 filterBy 中的函数。

只有函数返回结果为 true的数组元素才符合条件并将存入一个新的数组,最终返回结果即为这个新的数组。


2-3、orderBy

 orderBy 过滤器的作用是返回排序后的数组。过滤条件是:'string || array || function' + 'order>=0 为升序 || order<=0 为降序'.

第一个参数可以是字符串、数组或者函数,第二个参数order可选,决定结果为升序或降序排列,默认为1,即升序排列


若输入参数为字符串,则可同时传入多个字符串作为排序键名,字符串之间以空格分隔。代码示例如下:

1
2
3
4
5
<ul>
    <li v-for="user in users | orderBy 'lastName' 'firstName' 'age'">
        `user`.`lastName` `user`.`firstName` `user`.`age`
    </li>
</ul>


此时,将按照传入的排序键名的先后顺序进行排序。也可以将排序键名按照顺序放入一个数组中,然后传入一个数组参数给 orderBy 过滤器即可。代码示例如下:

1
2
3
4
5
6
<!--sortKey = ['lastName' 'firstName' 'age'];-->
<ul>
    <li v-for="user in users | orderBy sortKey">
        `user`.`lastName` `user`.`firstName` `user`.`age`
    </li>
</ul>


升序排列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
    <input type="text" v-model="a">
    <ul>
        <li v-for="val in arr | orderBy 1">
            `val`
        </li>
    </ul>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            a:'',
            arr:['pear','cherry','lemon','orange']
        }
    })
</script>

wKiom1g1GbmhGfZzAAAEDcpGg4I796.png


降序排列:

1
2
3
4
5
6
7
8
<div id="app">
    <input type="text" v-model="a">
    <ul>
        <li v-for="val in arr | orderBy -1">
            `val`
        </li>
    </ul>
</div>

wKioL1g1Gd7RC6EuAAAED57FhvM642.png


3、json 过滤器

Vue.js 中的 json 过滤器本质上是 JSON.stringify() 的精简缩略版,可将表达式的值转换为 JSON 字符串,即输出表达式经过 JSON.stringify() 处理后的结果。

json 可接受一个类型为 Number 的参数,用于决定转换后的 JSON 字符串的缩进距离,如果不输入该参数,则默认为2。


不输入参数,默认为2的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
    <p>{{information | json}}</p>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            information:{'name':'Roger', 'age':26}
        }
    })
</script>

wKiom1g1B1zySNhCAABQH_hsVKo325.png


为了看到效果,我们输入一个参数20:

1
2
3
<div id="app">
    <p>{{information | json 20}}</p<!-- 以20个空格的缩进打印一个对象 -->
</div>

wKioL1g1B4-QGcUrAABQPI5L4po940.png


4、currency 过滤器

currency 过滤器的作用是将数字值转换为货币形式输出。

第一个参数接受类型为 String 的货币符号,如果不输入,则默认为美元符号$。

第二个参数接受类型为 Number的小数位,如果不输入,则默认为2.

注意:如果第一个参数采取默认形式,而需要第二个参数修改小数位,则第一个参数不可省略


不输入参数,默认形式

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
    <h1>{{amount | currency}}</h1>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            amount: '12345'
        }
    })
</script>

wKiom1g1IzSA-QRcAAANRFF7ZKc117.png

使用其它货币符号:

1
2
3
<div id="app">
    <h1>{{amount | currency '¥'}}</h1>
</div>

wKiom1g1I2LSPKalAAAMoHPg3c0547.png

将小数调整为3位:

1
2
3
<div id="app">
    <h1>{{amount | currency '¥' 3}}</h1>
</div>

wKioL1g1I-DD5ifoAAANlVk-zsg324.png


5、debounce 过滤器

debounce 过滤器的作用是延迟处理一定的时间执行。其接受的表达式的值必须是函数,因此,一般与 v-on 等指令结合使用。


debounce 接受一个可选的参数作为延迟时间,单位为毫秒。如果没有该参数,则默认的延迟时间为300ms,经过 debounce 包装的处理器在调用之后将至少延迟设定的时间再执行。 如果在延迟结束前再次调用,则延迟时长将重置为设定的时间。


通常,在监听用户 input 事件时使用 debounce 过滤器比较有用,可以防止频繁调用方法。debounce 的用法参考如下:

1
<input @keyup="onKeyup | debounce 500">



自定义过滤器

1、filter语法

在Vue.js 中也存在一个全局函数 Vue.filter 用于构造过滤器:

Vue.filter(filterName, function(input){...})


该函数接受两个参数,第一个参数为自定义的过滤器名称,第二个参数则是具体的过滤器函数,过滤器函数以值为参数,返回转换后的值


2、单个参数

注册一个名为 reverse 的过滤器,作用是将字符串反转输出。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
    <input v-model="message">
    <span v-text="message | reverse">`message`</span>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    Vue.filter('reverse',function(message){
        return message.split('').reverse().join('');
    });
    new Vue({
        el:'#app',
        data:{
            message:''
        }
    })
</script>

wKiom1g1KK6RC32iAAAFTEKiIJU338.png

注册一个名为 double 的过滤器,作用是将数字补全成两位数输出。代码示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
    <input v-model="value">
    <p v-text="value | double">`value`</p>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    Vue.filter('double',function(value){
        return value<10? '0'+value : value
    });
    new Vue({
        el:'#app',
        data:{
            value:''
        }
    })
</script>

wKioL1g1KpmBD2S8AAAC-Q8KLs8796.png


注册一个名为 date 的过滤器,作用是将当前时间毫秒数以年月日时分秒的格式输出。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
    <p v-text="message | date">`message`</p>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    Vue.filter('date',function(message){
        var now = new Date(message);
        return now.getFullYear()+'-'
                +(now.getMonth()+1)+'-'
                +now.getDate()+' '
                +(now.getHours()<12?'0'+now.getHours():now.getHours())+':'
                +(now.getMinutes()<10?'0'+now.getMinutes():now.getMinutes())+':'
                +now.getSeconds();
    });
    new Vue({
        el:'#app',
        data:{
            message:Date.now()
        }
    })
</script>

wKioL1g1MXCjB1EpAAADjHeoDG4303.png


3、多个参数

过滤器函数除了以值作为参数外,也可以接受任意数量的参数,参数之间以空格分隔。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
    <input v-model="message">
    <p v-text="message | wrap 'before' 'end'">`message`</p>
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    Vue.filter('wrap',function(value, begin, end){
        return begin +' '+ value + ' '+ end
    });
    new Vue({
        el:'#app',
        data:{
            message:''
        }
    })
</script>

wKiom1g1LVmxEn2rAAAEl7hSot0349.png


4、双向过滤器

上面的过滤器都是在 Model 数据输出到 View 层之前进行数据转化的,实际上 Vue.js 还支持把来自视图(input元素)的值在写回模型前进行转化,即双向过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vue.filter('filterName',{
    //model ---> view
    //read 函数可选
    read:function(val){
        ...
    },
     
    //view ---> model
    //write 函数将在数据被写入Model 之前调用
    //两个参数分别为表达式的新值和旧值
    write:function(newVal, oldVal){
        ...
    }
})


代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
    <p>`message`</p>
    <input type="text" v-model="message | twoWayFilter">
</div>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    Vue.filter('twoWayFilter',{
        read:function(val){
            return 'read'+' '+val;
        },
        write:function(newVal, oldVal){
            return oldVal+' '+ 'write';
        }
    });
    new Vue({
        el:'#app',
        data:{
            message:'hello world'
        }
    })
</script>


在初始情况下,message 表达式的值经过 twoWayFilter 中的 read 函数处理,输出到 view 层

wKiom1g1NcHhsE1aAAAF2itqCSw188.png

当我们在 input 框中修改 message 的值时,twoWayFilter 中的 write 函数将在数据输出到 Model 层之前处理,这里将返回 message 的旧值 + 'write',然后输出到 Model层,因此 message的值变更为'hello world write' 并显示到页面上

wKioL1g1Nn-ib8HMAAAIt3AURKk053.png


常见问题解析

1、filterBy/orderBy 过滤后 $index 的索引

在使用 filterBy 或者 orderBy 对表达式进行过滤时,如果同时需要将 $index 作为参数,此时的 $index将会根据表达式数组或对象过滤后的值进行索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<ul id="app">
    <li v-for="item in items | orderBy 'age'">
        `item`.`name` - {{$index}}
    </li>
</ul>
 
<script src="//cdn.bootcss.com/vue/1.0.26/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        data:{
            items:[
                {name:'Roger', age:26},
                {name:'Sarahling', age:27},
                {name:'Daisy', age:1}
            ]
        }
    })
</script>

wKioL1g1ODOgcM4EAAAD1_wRwoA893.png


2、自定义filter 的书写位置

自定义 filter 可以写在全局 Vue下,例如:

1
2
3
Vue.filter('reverse',function(message){
        return message.split('').reverse().join('');
    });


也可以写在Vue 实例当中,例如:

1
2
3
4
5
6
7
8
9
10
11
12
var vm = new Vue({
    el:'#example',
    data:{
         
    },
    filters:{
        //自定义 filter 事件的位置
        reverse:function(value){
            return value.split('').reverse().join('');
        }
    }
})


二者本质上并无区别,可任选一种使用。但是,采用Vue.filter 在全局定义时,需要在实例化 Vue 之前定义,否则自定义的 filter 不起作用

本文转自   frwupeng517   51CTO博客,原文链接:
http://blog.51cto.com/dapengtalk/1875792

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9434 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
26715 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10823 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13106 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
11785 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4617 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6876 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
3986 0
5723
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载