与过滤器共享模板逻辑

为了共享模板逻辑,Vue.js 有过滤器(filters)。

过滤器可用于胡子插值 ({{ interpolatingSomething }}) 或表达式中(例如,绑定值时)。filter 是一个函数,它接受一个值并输出可以渲染的内容(通常是字符串(String)或数字(Number))。

因此,将在模板中使用名为 truncate 的示例过滤器,如下所示(此处,我们放置了一些长占位符文本):

<template>
    <div id="app">
        {{ message | truncate }}
    </div>
</template>

<script>
export default {
    data() {
        return {
            message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation llamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
        }
    }
}
</script>

truncate 也可以用在 Vue.js 绑定表达式中。例如, <MessageComponent :msg="message | truncate"> 会将 message 的截断输出绑定到 msg。

要定义截断(truncate)过滤器,我们可以在脚本(script)部分的组件的过滤器(filters)属性中定义它。

截断(truncate)过滤器会将文本截断为 120 个字符:

<script>
export default {
    filters: {
        truncate(value) {
            return value.slice(0, 120)
        }
    },
    // other component properties
}
</script>

没有截断过滤器,我们得到 lorem ipsum 的 446 个字符,如下:

image 2023 10 13 16 00 26 245
Figure 1. Figure 4.22: Lorem ipsum without truncation

使用截断(truncate)过滤器,我们将长度减少到 120 个字符,如下面的屏幕截图所示:

image 2023 10 13 16 01 14 029
Figure 2. Figure 4.23: Lorem ipsum with the truncate filter

编写此截断(truncate)过滤器的更具防御性的方法是,如果 val 为 false,则提前返回,然后在输出 .slice 之前对其进行 toString(例如,这会将数字转换为字符串):

<script>
export default {
    filters: {
        truncate(value) {
            if (!value) return
            const val = value.toString()
            return val.slice(0, 120)
        }
    },
    // other component properties
}
</script>

至此,我们学习了如何为组件注册和实现 Vue.js 过滤器。我们还学习了如何通过插值表达式的管道语法在组件模板中使用过滤器。

在下面的练习中,我们将学习如何实现省略号过滤器。

练习 4.05:实现省略过滤器

过滤器非常适合重复的文本处理任务。在本练习中,我们将实现一个省略号(ellipsis)过滤器,其工作原理如下。

如果传递的文本超过 14 个字符,则应将其截断为 11 个字符,并在文本末尾添加省略号 (…)。

当传递的文本为空或不是字符串时,我们应该非常宽容,要么不返回任何内容,要么在进行处理之前将其转换为字符串。

要访问本练习的代码文件,请参阅 https://packt.live/2IsZyuv

请按照以下步骤完成本练习:

  1. 首先,我们需要设置模板,以便它通过省略号管道传输小于 14 个字符的字符串、14 个字符的字符串以及超过 14 个字符的字符串,以检查它在所有可能的条件下是否按预期工作(我们将按照标准 Vue CLI 设置在 src/App.vue 中执行此操作)。我们还应该通过省略号(ellipsis)传递一个数字和一个空值(null):

    <template>
        <div id="app">
            <p>{{ '7 char' | ellipsis }}</p>
            <p>{{ '14 characters' | ellipsis }}</p>
            <p>{{ 'More than 14 characters' | ellipsis }}</p>
            <p>{{ null | ellipsis }}</p>
            <p>{{ 55 | ellipsis }}</p>
        </div>
    </template>

    在此阶段,应用程序应该只在控制台中显示文本。应该会出现一些省略号(ellipsis)过滤器未定义的警告,如下图所示:

    image 2023 10 13 16 07 32 611
    Figure 3. Figure 4.24: Application displaying unchanged text

    以下屏幕截图显示了警告:

    image 2023 10 13 16 08 07 741
    Figure 4. Figure 4.25: Vue.js warning that the ellipsis filter is missing
  2. 接下来,我们将在组件的脚本部分实现过滤器的初始版本。这将检查传递值的长度,将其截断为 11,如果长度超过 14 个字符,则添加 …:

    <script>
    export default {
        filters: {
            ellipsis(value) {
                return value.length > 14 ? `${value.slice(0, 11)}...` : value
            }
        }
    }
    </script>

    在此阶段,组件无法渲染,Vue.js 会记录一个错误,因为 Cannot read property 'length' of null,如以下屏幕截图所示:

    image 2023 10 13 16 10 17 207
    Figure 5. Figure 4.26: null piped into the application
  3. 接下来,我们需要修改省略号实现,以便在传递的值为 false 时短路(以避免出现 null 问题):

    ellipsis(value) {
        if (!value) return
        // rest of the function
    }

    我们现在已经可以使用省略(ellipsis)过滤器了;它适用于我们包含的所有测试用例。输出如下:

    image 2023 10 13 16 12 12 666
    Figure 6. Figure 4.27: Ellipsis filter working for given inputs

过滤器对于在组件中共享简单的文本处理逻辑非常有用。过滤器是一个 Vue.js 原语,它在模板中保留模板化和格式化问题,例如截断内容和添加省略号。

Vue.js 提供了对 DOM Web API 的抽象。然而,当需要直接访问 DOM 时,例如集成 DOM 库,Vue.js 提供了一种使用 refs 的方法。我们将在下一节中了解 Vue.js 引用。