問題
我們經常會用到過濾器filter,用於在處理變量的後操作。過濾器可以用在methods中,有兩種思路可以實現,一個是採用全局過濾器,以官方文檔中的代碼爲例:
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
methods:{
someMethod(){
const someValue = 'hello'
console.log(this.$options.filters['capitalize'](someValue)) // Hello
}
}
// ...
})
這樣便可以在methods中通過this.$options.filters[filter](...args)
的形式調用。
另一個是把公共的方法提取到一個文件中,然後export出來,在需要的時候在import進來,然後在所在的單文件組件中,添加本地過濾器,具體可以參加這篇文章,但是這個方法的缺點也很明顯,就是需要本地過濾器再寫一次,以便調用公共方法。
然而,filters中是否可以調用methods中的方法,也有網友提出,詳見這裏,但是並未給出答案。
分析
filters中的方法,都是純函數,不應該依賴外界或者對外界有所影響。(這是vue故意設計的,符合函數式思維,見Jasin Yip的回答)。全局filters和本地filters是爲了避免命名衝突和全局污染。全局filters和局部filters都無法獲取this,如想獲取,需要採用變通的方法,即在外面傳參,在調用過濾器的地方(template模板裏面),把this傳進去。譬如:
<detail-item label="員工狀態" :value="modelDetail.employeeStatus|employeeStatusFilter(this)"></detail-item>
這樣就需要改一下過濾器的定義,譬如:
employeeStatusFilter(value, that) { // that接受傳參this
// some code
},
還有一點需要注意,通過在template html傳參this,並不是Vue實例,而是Vue實例的代理對象,參見下圖:
如果要想獲得Vue實例,需要調用_self
方法,即:
const _this = that._self // _this即爲Vue實例
然後,我們就可以調用methods、data中的方法和屬性了,即:
employeeStatusFilter(value, that) {
const _this = that._self
return _this.pickLabel(_this.employeeStatusOptions, value) //pickLabel爲methods中的一個方法
},
總結
- template傳參
- _self獲取Vue實例
- 調用methods中的方法