• 过滤器
    • 插入文本之外的过滤器 移除
      • 替换 debounce 过滤器
      • 替换 limitBy 过滤器
      • 替换 filterBy 过滤器
      • 替换 orderBy 过滤器
      • 升级方式
    • 过滤器参数符号 变更
      • 升级方式
    • 内置文本过滤器 移除
      • 替换 json 过滤器
      • 替换 capitalize 过滤器
      • 替换 uppercase 过滤器
      • 替换 lowercase 过滤器
      • 替换 pluralize 过滤器
      • Replacing the currency Filter
      • 升级方式
    • 双向过滤器 替换
      • 升级方式

    过滤器

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

    现在过滤器只能用在插入文本中 ({{ }} 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 的指令中使用过滤器的例子。如果你错过了,则应该会收到命令行报错