過濾器,本質上就是一個函數。其做用在於用戶輸入數據後,它可以進行處理,並返回一個數據結果。
css
Vue.js 與 AngularJS 中的過濾器語法有些類似,使用管道符(|)進行鏈接,代碼示例以下:html
{{'abc' | uppercase}} 'abc' => 'ABC'
這裏使用了Vue.js 內置的過濾器 uppercase,將字符串中的字母所有轉換成大寫形式。vue
Vue.js 支持在任何出現表達式的地方添加過濾器,除了上面例子中的 雙大括號 表達式以外,還能夠在綁定指令的表達式後調用,代碼示例以下:json
<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!api
Vue 2.x 中,過濾器只能在 mustache 綁定中使用。爲了在指令綁定中實現一樣的行爲,你應該使用計算屬性。數組
過濾器能夠串聯:app
{{ message | filterA | filterB }}
這裏能夠看一個例子:ide
<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過濾器:把首字母變成大寫形式spa
// 'ABCDE' -> 'abcde' -> 'Abcde'
過濾器能夠接受參數,參數跟在過濾器名稱後面,參數之間以空格分隔。代碼示例以下:
{{ message | filterA('arg1', arg2) }}
過濾器函數將始終以表達式的值做爲第一個參數,帶引號的參數會被看成字符串處理,而不帶引號的參數會被看成數據屬性名來處理。
這裏的 message 將做爲第一個參數,字符串arg1 做爲第二個參數,表達式 arg2 的值在計算出來之後做爲第三個參數傳給過濾器。同時,Vue.js 的過濾器支持鏈式調用,上一個過濾器的輸出結果能夠做爲下一個過濾器的輸入
內置過濾器
必須指出的是,在Vue2.0中,刪除了全部的內置過濾器
一、字母操做
Vue.js 內置了 capitalize、uppercase、lowercase 三個過濾器用於處理英文字符。注意:這三個過濾器僅針對英文字符串使用
1-一、capitalize
capitalize 過濾器用於將表達式中的首字母轉換爲大寫形式
{{'abc' | capitalize}} // 'abc' => 'Abc'
1-二、uppercase
uppercase 過濾器用於將表達式中的全部字母轉換爲大寫形式
{{'abc' | uppercase}} // 'abc' => 'ABC'
1-3、lowercase
lowercase 過濾器用於將表達式中的全部字母轉換爲小寫形式
{{'ABC' | lowercase}} // 'ABC' => 'abc'
二、限制
Vue.js 中內置了 limitBy、filterBy、orderBy 三個過濾器用於處理並返回過濾後的數組,好比與v-for搭配使用。
注意:這三個過濾器所處理的表達式的值必須是數組,不然程序會報錯
2-一、limitBy
limitBy 過濾器的做用是限制數組爲開始前的 N 個元素,其中,N 由傳入的第一個參數指定,表示限制幾個,默認爲 0, 即取所有的元素。第二個參數可選,用於指定從哪開始,好比:第一個參數是4,第二個參數是5,則表示取4個元素,從下標爲5的元素開始。代碼示例以下:
<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>
<div id="app"> <ul> <!--只顯示5個元素,從0開始--> <li v-for="item in items | limitBy 5">`item`</li> </ul> </div>
<div id="app"> <ul> <!--顯示4個,從下標爲3的元素開始 注意:下標是從0開始--> <li v-for="item in items | limitBy 4 3">`item`</li> </ul> </div>
還能夠這麼使用:
<div id="app"> <ul> <!--取6個,從下標爲4的元素開始 注意:數組的長度是arr.length --> <li v-for="item in items | limitBy items.length-4 4">`item`</li> </ul> </div>
2-二、filterBy
filterBy過濾器的使用比較靈活,其第一個參數能夠是字符串或者函數,過濾條件是:'string || function' + in + 'optionKeyName'
若是第一個參數是字符串,那麼將在每一個數組元素中搜索它,並返回包含該字符串的元素組成的數組。代碼示例以下:
<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>
若是數組元素是一個對象,過濾器將遞歸地在它全部屬性中搜索。爲了縮小搜索範圍,能夠指定一個搜索字段。代碼示例以下:
<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>
若是 filterBy 的第一個參數是函數,則過濾器將根據函數的返回結果進行過濾。此時 filterBy過濾器將調用 Javascript 數組中內置的函數 filter() 對數組進行處理,待過濾數組中的每一個元素都將做爲參數輸入並執行傳入 filterBy 中的函數。
只有函數返回結果爲 true的數組元素才符合條件並將存入一個新的數組,最終返回結果即爲這個新的數組。
2-三、orderBy
orderBy 過濾器的做用是返回排序後的數組。過濾條件是:'string || array || function' + 'order>=0 爲升序 || order<=0 爲降序'.
第一個參數能夠是字符串、數組或者函數,第二個參數order可選,決定結果爲升序或降序排列,默認爲1,即升序排列
若輸入參數爲字符串,則可同時傳入多個字符串做爲排序鍵名,字符串之間以空格分隔。代碼示例以下:
<ul> <li v-for="user in users | orderBy 'lastName' 'firstName' 'age'"> `user`.`lastName` `user`.`firstName` `user`.`age` </li> </ul>
此時,將按照傳入的排序鍵名的前後順序進行排序。也能夠將排序鍵名按照順序放入一個數組中,而後傳入一個數組參數給 orderBy 過濾器便可。代碼示例以下:
<!--sortKey = ['lastName' 'firstName' 'age'];--> <ul> <li v-for="user in users | orderBy sortKey"> `user`.`lastName` `user`.`firstName` `user`.`age` </li> </ul>
升序排列:
<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>
降序排列:
<div id="app"> <input type="text" v-model="a"> <ul> <li v-for="val in arr | orderBy -1"> `val` </li> </ul> </div>
三、json 過濾器
Vue.js 中的 json 過濾器本質上是 JSON.stringify() 的精簡縮略版,可將表達式的值轉換爲 JSON 字符串,即輸出表達式通過 JSON.stringify() 處理後的結果。
json 可接受一個類型爲 Number 的參數,用於決定轉換後的 JSON 字符串的縮進距離,若是不輸入該參數,則默認爲2。
不輸入參數,默認爲2的示例:
<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>
爲了看到效果,咱們輸入一個參數20:
<div id="app"> <p>{{information | json 20}}</p> <!-- 以20個空格的縮進打印一個對象 --> </div>
四、currency 過濾器
currency 過濾器的做用是將數字值轉換爲貨幣形式輸出。
第一個參數接受類型爲 String 的貨幣符號,若是不輸入,則默認爲美圓符號$。
第二個參數接受類型爲 Number的小數位,若是不輸入,則默認爲2.
注意:若是第一個參數採起默認形式,而須要第二個參數修改小數位,則第一個參數不可省略
不輸入參數,默認形式
<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>
使用其它貨幣符號:
<div id="app"> <h1>{{amount | currency '¥'}}</h1> </div>
將小數調整爲3位:
<div id="app"> <h1>{{amount | currency '¥' 3}}</h1> </div>
五、debounce 過濾器
debounce 過濾器的做用是延遲處理必定的時間執行。其接受的表達式的值必須是函數,所以,通常與 v-on 等指令結合使用。
debounce 接受一個可選的參數做爲延遲時間,單位爲毫秒。若是沒有該參數,則默認的延遲時間爲300ms,通過 debounce 包裝的處理器在調用以後將至少延遲設定的時間再執行。 若是在延遲結束前再次調用,則延遲時長將重置爲設定的時間。
一般,在監聽用戶 input 事件時使用 debounce 過濾器比較有用,能夠防止頻繁調用方法。debounce 的用法參考以下:
<input @keyup="onKeyup | debounce 500">
自定義過濾器
一、filter語法
在Vue.js 中也存在一個全局函數 Vue.filter 用於構造過濾器:
Vue.filter(filterName, function(input){...})
該函數接受兩個參數,第一個參數爲自定義的過濾器名稱,第二個參數則是具體的過濾器函數,過濾器函數以值爲參數,返回轉換後的值
二、單個參數
註冊一個名爲 reverse 的過濾器,做用是將字符串反轉輸出。代碼示例以下:
<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>
註冊一個名爲 double 的過濾器,做用是將數字補全成兩位數輸出。代碼示例以下
<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>
註冊一個名爲 date 的過濾器,做用是將當前時間毫秒數以年月日時分秒的格式輸出。代碼示例以下:
<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>
三、多個參數
過濾器函數除了以值做爲參數外,也能夠接受任意數量的參數,參數之間以空格分隔。代碼示例以下:
<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>
四、雙向過濾器
上面的過濾器都是在 Model 數據輸出到 View 層以前進行數據轉化的,實際上 Vue.js 還支持把來自視圖(input元素)的值在寫回模型前進行轉化,即雙向過濾器
Vue.filter('filterName',{ //model ---> view //read 函數可選 read:function(val){ ... }, //view ---> model //write 函數將在數據被寫入Model 以前調用 //兩個參數分別爲表達式的新值和舊值 write:function(newVal, oldVal){ ... } })
代碼示例以下:
<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 層
當咱們在 input 框中修改 message 的值時,twoWayFilter 中的 write 函數將在數據輸出到 Model 層以前處理,這裏將返回 message 的舊值 + 'write',而後輸出到 Model層,所以 message的值變動爲'hello world write' 並顯示到頁面上
常見問題解析
一、filterBy/orderBy 過濾後 $index 的索引
在使用 filterBy 或者 orderBy 對錶達式進行過濾時,若是同時須要將 $index 做爲參數,此時的 $index將會根據表達式數組或對象過濾後的值進行索引
<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>
二、自定義filter 的書寫位置
自定義 filter 能夠寫在全局 Vue下,例如:
Vue.filter('reverse',function(message){ return message.split('').reverse().join(''); });
也能夠寫在Vue 實例當中,例如:
var vm = new Vue({ el:'#example', data:{ }, filters:{ //自定義 filter 事件的位置 reverse:function(value){ return value.split('').reverse().join(''); } } })
兩者本質上並沒有區別,可任選一種使用。可是,採用Vue.filter 在全局定義時,須要在實例化 Vue 以前定義,不然自定義的 filter 不起做用