过滤器

插入文本之外的过滤器 移除

现在过滤器只能用在插入文本中 ({{ }} tags)。我们发现在指令 (如:v-modelv-on等) 中使用过滤器使事情变得更复杂。像v-for 这样的列表过滤器最好把处理逻辑作为一个计算属性放在 js 里面,这样就可以在整个模板中复用。

总之,能在原生 js 中实现的东西,我们尽量避免引入一个新的符号去重复处理同样的问题。下面是如何替换 Vue 内置过滤器:

替换 debounce 过滤器

不再这样写

  1. <input v-on:keyup="doStuff | debounce 500">
  1. methods: {
  2. doStuff: function () {
  3. // ...
  4. }
  5. }

请使用 lodash’s debounce (也有可能是 throttle) 来直接控制高耗任务。可以这样来实现上面的功能:

  1. <input v-on:keyup="doStuff">
  1. methods: {
  2. doStuff: _.debounce(function () {
  3. // ...
  4. }, 500)
  5. }

这种写法的更多优点详见:v-model 示例

替换 limitBy 过滤器

不再这样写:

  1. <p v-for="item in items | limitBy 10">{{ item }}</p>

在 computed 属性中使用 js 内置方法:.slice method

  1. <p v-for="item in filteredItems">{{ item }}</p>
  1. computed: {
  2. filteredItems: function () {
  3. return this.items.slice(0, 10)
  4. }
  5. }

替换 filterBy 过滤器

不再这样写:

  1. <p v-for="user in users | filterBy searchQuery in 'name'">{{ user.name }}</p>

在 computed 属性中使用 js 内置方法 .filter method

  1. <p v-for="user in filteredUsers">{{ user.name }}</p>
  1. computed: {
  2. filteredUsers: function () {
  3. var self = this
  4. return self.users.filter(function (user) {
  5. return user.name.indexOf(self.searchQuery) !== -1
  6. })
  7. }
  8. }

js 原生的 .filter 同样能实现很多复杂的过滤器操作,因为可以在计算 computed 属性中使用所有 js 方法。比如,想要通过匹配用户名字和电子邮箱地址 (不区分大小写) 找到用户:

  1. var self = this
  2. self.users.filter(function (user) {
  3. var searchRegex = new RegExp(self.searchQuery, 'i')
  4. return user.isActive && (
  5. searchRegex.test(user.name) ||
  6. searchRegex.test(user.email)
  7. )
  8. })

替换 orderBy 过滤器

不这样写:

  1. <p v-for="user in users | orderBy 'name'">{{ user.name }}</p>

而是在 computed 属性中使用 lodash’s orderBy (或者可能是 sortBy):

  1. <p v-for="user in orderedUsers">{{ user.name }}</p>
  1. computed: {
  2. orderedUsers: function () {
  3. return _.orderBy(this.users, 'name')
  4. }
  5. }

甚至可以字段排序:

  1. _.orderBy(this.users, ['name', 'last_login'], ['asc', 'desc'])

升级方式

运行迁移工具找到指令中使用的过滤器。如果有些没找到,看看控制台错误信息

过滤器参数符号 变更

现在过滤器参数形式可以更好地与 js 函数调用方式一致,因此不用再用空格分隔参数:

  1. <p>{{ date | formatDate 'YY-MM-DD' timeZone }}</p>

现在用圆括号括起来并用逗号分隔:

  1. <p>{{ date | formatDate('YY-MM-DD', timeZone) }}</p>

升级方式

运行迁移工具找到老式的调用符号,如果有遗漏,请看控制台错误信息

内置文本过滤器 移除

尽管插入文本内部的过滤器依然有效,但是所有内置过滤器已经移除了。取代的是,推荐在每个区域使用更专业的库来解决。(比如用 date-fns 来格式化日期,用 accounting 来格式化货币)。

对于每个内置过滤器,我们大概总结了下该怎么替换。代码示例可能写在自定义 helper 函数,方法或计算属性中。

替换 json 过滤器

不用一个个改,因为 Vue 已经帮你自动格式化好了,无论是字符串,数字还是数组,对象。如果想用 js 的 JSON.stringify 功能去实现,你也可以把它写在方法或者计算属性里面。

替换 capitalize 过滤器

  1. text[0].toUpperCase() + text.slice(1)

替换 uppercase 过滤器

  1. text.toUpperCase()

替换 lowercase 过滤器

  1. text.toLowerCase()

替换 pluralize 过滤器

NPM 上的 pluralize 库可以很好的实现这个功能。如果仅仅想将特定的词格式化成复数形式或者想给特定的值 (‘0’) 指定特定的输出,也可以很容易地自定义复数格式化过滤器:

  1. function pluralizeKnife (count) {
  2. if (count === 0) {
  3. return 'no knives'
  4. } else if (count === 1) {
  5. return '1 knife'
  6. } else {
  7. return count + 'knives'
  8. }
  9. }

Replacing the currency Filter

对于简单的问题,可以这样做:

  1. '$' + price.toFixed(2)

大多数情况下,仍然会有奇怪的现象 (比如 0.035.toFixed(2) 向上取舍得到 0.04,但是 0.045 向下取舍却也得到 0.04)。解决这些问题可以使用 accounting 库来实现更多可靠的货币格式化。

升级方式

运行迁移工具找到舍弃的过滤器。如果有些遗漏,请参考控制台错误信息

双向过滤器 替换

有些用户已经乐于通过 v-model 使用双向过滤器,以很少的代码创建有趣的输入。尽管表面上很简单,双向过滤器也会暗藏一些巨大的复杂性——甚至促使状态更新变得迟钝影响用户体验。推荐用包裹一个输入的组件取而代之,这样以更显性且功能更丰富的方式创建自定义的输入。

我们现在做一次双向汇率过滤器的迁移作为示范:

它基本工作良好,但是拖延的状态更新会导致奇怪的行为。比如,点击 Result 标签,试着在其中一个输入框中输入 9.999。当输入框失去焦点的时候,其值将会更新到 $10.00。然而当我们从整个计算器的角度看时,你会发现存储的数据是 9.999。用户看到的已经不是真实的同步了!

为了过渡到一个更加健壮的 Vue 2.0 的方案,让我们首先在一个新的 <currency-input> 组件中包裹这个过滤器:

它允许我们添加独立过滤器无法封装的行为,比如选择输入框聚焦的内容。下一步我们从过滤器中提取业务逻辑。接下来是我们把所有的东西放到一个外部的 currencyValidator 对象中:

这会更加模块化,不只是更容易的迁移到 Vue 2,同时也允许汇率间隙和格式化:

  • 从你的 Vue 代码中独立出来进行单元测试
  • 在你的应用程序的别的部分中使用,比如验证验证一个 API 端的负荷 把这个验证器提取出来之后,我们也可以更舒适的把它构建到更健壮的解决方案中。那些古怪的状态也消除了,用户不再可能会输入错误,就像浏览器原生的数字输入框一样。

然而在 Vue 1.0 的过滤器中,我们仍然是受限的,所以还是完全升级到 Vue 2.0 吧:

你可能注意到了:

  • 我们的输入框的各方面都更显性,使用生命周期钩子和 DOM 事件以替代双向过滤器的隐藏行为。
  • 我们现在可以在自定义输入框中直接使用 v-model,其不只是固定配合正常的输入框来使用,这也意味着我们的组件是对 Vuex 友好的。
  • 因为我们已经不再要求过滤器选项必须要有一个返回值,所以实际上我们的汇率工作可以异步完成。这意味着如果我们有很多应用需要和汇率打交道,我们可以轻松的提炼这个逻辑并成为一个共享的微服务。

升级方式

运行迁移工具找到在例如 v-model 的指令中使用过滤器的例子。如果你错过了,则应该会收到命令行报错