一直没有怎么用过 Vue 的 过滤器 API,都是直接用 AntD Pro 当中提供的数字千分格式化、时间格式化之类的,没有自己去声明过,主要是因为 Array.prototype.filter
的先入为主,一直把 vue.filter
理解成为了筛选,而不是过滤器。
其实,vue.filter
是借鉴了 Linux 当中的 Pipe 符号 (|
) 来处理数据 ,然后借用了 filter
这个名字:
利用 Linux 所提供的管道符 “
|
” 将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入
其实我觉得如果直接用 pipe
来命名其实就更好理解了,但是也许是因为前端圈子接触到 pipe
的人并不多,使用 filter
这个熟悉的单词可能更加容易让大众接受。
使用起来确实很方便,用 |
符号分隔就行,会按照 从前往后的顺序 依次 传入过滤器,然后返回转换后的值。
等到后来再遇到适合的场景想起来使用 filter
,但又因为项目的历史原因没有去使用,因为自己都是局部使用 computed
计算 和 方法调用返回 来处理(也是Vue3所推荐的替代过滤器的方式)
初步使用:在组件中使用过滤器
过滤器可以用在两个地方(可以直接的使用方式有 2 种)
- 在双花括号中
{{ message | filterName }}
; - 在
v-bind
中<div v-bind:id="message | filterName"></div>
。
那如果说我要使用多个过滤器呢?
例如:{{ message | filterA | filterB }}
会先传入 filterA
去处理,filterA
返回的结果继续传入给 filterB
最后展示的值就是 filterB
返回的结果。
🌰 DEMO:
<template>
<div id="app">
<span>{{ price | NumberFormat | FilterDollarSign }}</span>
<!-- 渲染结果是 $ 199,999,999 -->
</div>
</template>
<script>
export default {
data() {
return {
price:199999999,
};
},
filters:{
NumberFormat(value) {
if (!value) return '0'
const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
return intPartFormat
},
FilterDollarSign(price){
return `$ ${price}`
}
},
};
</script>
✨ 多参数 过滤器 的情况
例如,需要传入 两个参数 的过滤器,刨开第一个默认传入的参数,键入第二个参数即可: {{ price | NumberFormat(2) }}
, 三个参数: {{ price | NumberFormat(2, '$') }}
,更多参数以此类推。
<template>
<div id="app">
<span>{{ price | NumberFormat(2, '$') }}</span>
<!-- 渲染结果是 $ 0.67 -->
</div>
</template>
<script>
export default {
data() {
return {
price:0.6666,
};
},
filters:{
NumberFormat(value, limit, sign) {
if (!value) return '0'
const intPartFormat = value.toFixed(limit).toString()
return `${sign} ${intPartFormat}`
}
},
};
</script>
更进一步:使用全局过滤器
在项目的不断完善中,会有出现一些重复使用的过滤器,如果每次都重新声明就很麻烦,就可以注册 全局过滤器 vue.filter
🌰 栗子:
// main.js
Vue.filter('NumberFormat', function (value) {
if (!value) {
return '0'
}
const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
return intPartFormat
})
new Vue({
// options
}).$mount('#app')
然后就可以在全局直接使用这个过滤器了,不需要单独再声明或者引入。
当然如果全部都直接在 main.js
当中书写很多过滤器就很容易让 main.js
内容过多,所以可以提取出来,例如 ant-design-vue-pro/filter.js,然后再 import
进来就可以了 ant-design-vue-pro/main.js
✨ 全局和局步同名冲突
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
✨ 以上说的都是在 <template>
当中使用过滤器,如果我想在 methods
当中使用呢?
全局过滤器的话,可以直接使用文档中的 var myFilter = Vue.filter('my-filter')
来获取,然后就可以把 myFilter
当成一个函数使用了,
如果时当前组件的过滤器的,可以使用 this.$options.filters['my-filter']
来获取,调用方式和上边一样。
🎐 尾声
适合过滤器的场景
一般是简单的字符串处理,例如上边提到的添加数字千分号、把 状态key 转换成 状态label 之类的。
过滤器中如何使用当前组件的 data
或者 methods
之类
参看上条,如果需要使用 data
、computed
和 methods
之类请使用 computed
替代 filter
VueJS 3.x 当中的 filter
已删除
In
3.x
, filters are removed and no longer supported. Instead, we recommend replacing them with method calls or computed properties.
在3.x
中,过滤器已删除,不再支持。相反地,我们建议用方法调用或计算属性替换它们。