Vue 中的过滤器
整理 Vue 中的过滤器相关知识
注册
全局注册
使用 Vue.filter('filterName', fn)
注册全局过滤器,一般写在 main.js 里,项目中常见写法如下
// utils/filters.js
export default {
filterFn1 () {},
filterFn2 () {}
}
// main.js
import filters from './utils/filters'
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
局部(组件内)注册
在一个组件的选项中定义
filters: {
filterFn: function (value) {
return value
}
}
ts + vue-property-decorator 的写法
@Component({
filters: {
filterFn: function (value) {
return value
}
}
})
export default class XXX extends Vue {}
使用
模板内使用
使用管道符号 |
作为参数和过滤器名字的分隔,可以链式调用,可以传入更多参数。可以在 v-bind
和插值中使用,链式调用时上个函数的返回值会作为下个函数的入参,传入多个参数时,管道符号前面的是第一个参数,过滤器函数括号中传入剩余参数
<template>
<div>
<div
v-for="item in (0, 3)"
:key="item"
:class="item | filterClass"
>
<div>链式调用: {{ item | filterVal | addTime }}</div>
<div>多个参数: {{ item | addTime('2021', '07') }}</div>
</div>
</div>
</template>
<script>
export default {
filters: {
filterClass: function (val) {
return 'text-' + val
},
filterVal: function (val) {
return `这是第${val}个栗子`
},
addTime: function (val, year = '2020', month = '01') {
return `${val}, ${year}-${month}`
}
}
};
</script>
<style scoped>
.text-1 {
color: red;
}
.text-2 {
color: blue;
}
.text-2 {
color: green;
}
</style>
JS调用
- 调用全局过滤器
const filterFn = Vue.filter('filterFn')
- 调用局部过滤器
const filterFn = this.$options.filters('filterFn')
限制
在 filters 中是无法访问 this 的,这点要注意,尤雨溪也提到过这个问题,因为过滤器被认为是纯函数,它不应当能访问上下文,如果你要使用 this ,你可以使用一个计算属性或者一个 methods 方法。详见 https://github.com/vuejs/vue/issues/5998#issuecomment-311965292 ,可以通过传参的方式来破解,将需要的属性传入进去使用即可。
场景
顺带着谈谈 computed、 methods 和 filters 的使用场景,这三个都是函数的用法,你可以传入值,然后获取返回值
计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的。methods 每次调用都会执行。filter 在每次模板编译的时候执行。在编码中依据实际情况选择适合的使用即可。
一般 filter 我会用来进行比较多的数据的转换,而且这种数据转换和页面的响应数据关系不大的,比如说我们常有处理表格数据的需求,给某列统一加上百分千分符之类的,用过滤器来做就很方便,而且这是全局通用的逻辑,需要更改的话只改源处。计算属性用在单个值上比较划算,比如要从数组中过滤出一个特殊数组,用计算属性缓存这个特殊数组的值,只要源数据不变,这个值一直有缓存无需重新计算。如果是当前页面的独有的计算,和页面的响应式属性关联比较多的计算,并且不需要链式调用(这一般还真是用不太到),选择使用 methods 来处理。
原理&源码
待续。。。