[toc]
## 基礎
和自定義指令類似,你可以用全局方法 Vue.filter(),傳遞一個過濾器 ID 和一個過濾器函數來注冊一個自定義過濾器。過濾器函數會接受一個參數值并返回將其轉換后的值:
~~~
Vue.filter('reverse', function (value) {
return value.split('').reverse().join('')
})
<!-- 'abc' => 'cba' -->
<span v-text="message | reverse"></span>
過濾器函數也可以接受內聯參數:
Vue.filter('wrap', function (value, begin, end) {
return begin + value + end
})
<!-- 'hello' => 'before hello after' -->
<span v-text="message | wrap 'before' 'after'"></span>
~~~
## 雙向過濾器
到目前為止,我們使用過濾器都是把來自模型的值在顯示到視圖之前進行轉換。其實我們也可以定義一個過濾器,在把來自視圖的值(input 元素)在寫回模型之前進行轉換:
~~~
Vue.filter('check-email', {
// 這里 read 可選,只是為了演示
read: function (val) {
return val
},
// write 函數會在數據寫入到模型之前被調用
write: function (val, oldVal) {
return isEmail(val) ? val : oldVal
}
})
~~~
## 動態參數
如果一個過濾器參數沒有被引號包裹,它會在當前 vm 的數據作用域里當做表達式進行動態求值。此外,過濾器函數的 this 上下文永遠是調用它的當前 vm。
~~~
<input v-model="userInput">
<span>{{msg | concat userInput}}</span>
Vue.filter('concat', function (value, input) {
// 這里 `input` === `this.userInput`
return value + input
})
~~~
在上面這個例子中,顯然用內聯表達式也可以達成相同的效果。但是面對更復雜的需求時,常常需要不止一個語句,這種情況下你就得把邏輯放到一個計算屬性中或是一個自定義過濾器中。
內建的 filterBy 和 orderBy 過濾器都是根據當前 Vue 實例的狀態對傳入的數組進行處理。