Vue学习笔记之--过滤器

刚开始使用vue进行项目重构的时候,对于一些需要固定规则的变量,往往会通过计算属性进行实现,比如这样:

1
2
3
4
5
6
7
8
9
10
11
data: function() {
return {
imgUrl: './a.jpg'
}
},
computed: {
imgSrc: function() {
return `src(${this.imgUrl})`;
}
}

这种方式效果明显不是最好的。只需要用一个变量进行维护的值我们需要用两个变量进行控制,
增加了很多不必要的代码,而直接在template中进行拼接也不合适。

终于,又过了一遍vue文档的时候发现了可以很好解决这个问题的东西–过滤器。

使用姿势

1
2
3
4
<img :src="imgUrl | capitalize" />
<!-- or -->
{{ msg || capitalize }}

通过这种方式可以直接对变量进行过滤处理,方便、直观,酷!

常用过滤器

官网给出了几种常用过滤器,直接抄几个常用的在这里,方便查看。

  • uppercase 大写
  • lowercase 小写
  • debounce 函数延迟执行(必须是函数

    1
    <input @keyup="onKeyup | debounce 500">
  • limitBy 限制指令执行个数,如:

    1
    2
    3
    4
    5
    <!-- 只显示开始 10 个元素 -->
    <div v-for="item in items | limitBy 10"></div>
    <!-- 显示第 5 到 15 元素-->
    <div v-for="item in items | limitBy 10 5"></div>
  • filterBy: 过滤数组,跟我们平时使用.filter()方式类似,很好用噢

    • 参数为字符串,返回包含此字符串的元素

      1
      2
      <!-- 返回带hello的元素 -->
      <div v-for="item in items | filterBy 'hello'">
    • 降低缩小范围

      1
      2
      <!-- 返回属性name为Jack的user -->
      <div v-for="user in users | filterBy 'Jack' in 'name'">
    • 上面两种,就很酷的实现了模糊搜索呀!

    • 使用自己写的filter函数
      1
      <div v-for="user in users | filterBy myCustomFilterFunction">
  • orderBy 排序
    排序功能也很酷有没有!!!直观有效是不是!!直接看代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!-- 按照name排序 -->
    <li v-for="user in users | orderBy 'name'">
    <!-- 规定顺序 >= 0 升序 | <0 降序 -->
    <li v-for="user in users | orderBy 'name' 1">
    <!-- 原始类型的数组可以直接忽略键名 -->
    <li v-for="user in users | orderBy 1">
    <!-- 使用sortFunction排序,和.sort()类似 -->
    <li v-for="user in users | orderBy sortFunction">

自定义过滤器

几种常用的方式,一个个抄下来感觉已经大部分满足我们的日常需要,
而我们经常使用像文章开头那样的,src,url这类东西的时候,往往定义一些自己的过滤器方便使用,
使用姿势如下:

1
2
3
4
5
6
//自定义过滤器的方式很简单,和我们日常书写filter函数一样
//通过Vue.filter()进行注册
Vue.filter('name', function(value){
return 'name:' + value;
});

双向过滤器

对于Input等进行双向数据绑定的元素,我们可以通过read,write来控制过滤的时机。
我们来看看官网的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
Vue.filter('currencyDisplay', {
// model -> view
// 在更新 `<input>` 元素之前格式化值
read: function(val) {
return '$'+val.toFixed(2)
},
// view -> model
// 在写回数据之前格式化值
write: function(val, oldVal) {
var number = +val.replace(/[^\d.]/g, '')
return isNaN(number) ? 0 : parseFloat(number.toFixed(2))
}
})

乍一看,对于双向数据绑定理解不太深刻的同学可能不太理解这个意思(比如我。让我们来尝试一下:

首先,我们在一个v-model里直接添加一个普通的过滤器:

1
2
3
4
5
6
<p>{{ msg }}</p>
<input type="text" v-model="msg | test">
Vue.filter('test', function (val) {
return val + 'test';
});

结果就是,提示警告,并且输入框输入变化时,msg值并没有变化。让我们使用双向过滤器尝试一下,到底发生了什么。
首先我们写一个双向过滤器:

1
2
3
4
5
6
7
8
9
10
Vue.filter('test', {
read: function (val) {
console.log('read' + val);
return val + 'test1';
},
write: function(val) {
console.log('write' + val);
return val + 'test2';
}
});

将这个过滤器添加到普通的Mustache标签内,看看效果。

1
2
3
4
<p>{{ msg | test }}</p>
<input type="text" v-model="msg">
// => 'read' + val

每当输入变化时,显示’read’ + 新的值。所以日常的Mustache标签只使用read过滤方法,
即当model改变后->view渲染前,调用过滤器进行过滤。

下面我们将这个过滤器添加到v-model内:

1
2
3
4
5
<p>{{ msg }}</p>
<input type="text" v-model=" msg | test ">
// => 'write' + val
// => 'read' + val + 'test2'

每当输入变化时,控制台先输出’write’,也就是在数据写入model时进行过滤,
model存入过滤后的值,Mustache标签会自动渲染为write函数过滤后的值。
而当input 失焦时,触发view的更新,也就是会根据model => view,此时才会调用read过滤器,将’test1’加入到value内。

总结下:

  • read: 只针对 model => view 来进行过滤
  • write: 针对写入model前进行过滤

我们可以按需选择进行使用。