Vue 指令

Vue 的模板语言允许您使用 JavaScript 表达式和 Vue 指令对 HTML 代码进行插值。这种模板模式通常被称为语法糖,因为它不会改变代码本身的工作方式,只是改变了您使用代码的方式。语法糖允许您在 HTML 中清晰地定义特定于模板的逻辑,而无需在项目的其它地方抽象这些逻辑或直接从 JavaScript 代码中返回大量 HTML。所有基于 Vue 的指令都以 v-* 作为前缀,表示它是 Vue 特有的属性:

  • v-text: v-text 指令与 插值指令 具有相同的响应性,只是在指令中引用的是同一段数据。插值(大括号){{ }}v-text 指令的性能更高;不过,您可能会发现自己处于这样一种情况,即您已从服务器预渲染了文本,并希望在加载 Vue 应用程序后覆盖它。例如,您可以预先定义静态占位符文本,而 DOM 会等待 datav-text 属性并最终替换它。

  • v-once: 作为一个指令,它的独特之处在于可以与其它指令搭配使用,以增强它们的功能。通过 v-text 或内插大括号向添加了该属性的 HTML 元素传递数据,将阻止 Vue 实例使用新数据重新加载元素,从而消除元素的响应性。如果您想使用数据渲染装饰元素,但又不想在初始渲染后数据发生变化时对其进行更新,那么这将非常方便。

  • v-html: 该指令将在绑定的 HTML 元素内的数据字符串中渲染有效的 HTML。与其它指令相比,该指令的操作较为繁琐,因此建议在没有其它选项的情况下有限使用。

    <script> 标签可以在此指令中运行。仅渲染来自安全或可信来源的内容。

  • v-bind: 该指令是 Vue 中使用最广泛的指令之一。在整个 Vue 中,您将使用该指令的 :attr 快捷方式(而不是 v-bind:attr)将反应数据绑定到 HTML 属性,并将数据传递到 props 中。

  • v-if: 为了控制模板内 HTML 元素的显示状态,您通常会使用 v-if 将元素从 DOM 树中完全移除。到目前为止,您已经看到了如何插值条件,如 {{ isTrue ? 'Show this' : 'Not this'}}v-else-if 可以像 else if 语句一样使用,并以 v-else 结束,相当于 else { ... } 语句的 catch { ... } 声明。

  • v-show: 您可以使用 v-show 控制 HTML 元素的可见状态,它不会从 DOM 树中删除元素,而是应用 display: none 样式。 v-ifv-show 之间的区别在于 v-show 将作为 DOM 树中的块元素保留,但会使用 css 隐藏,而不是从 DOM 树中删除。您也不能将 v-showv-elsev-else-if 链式使用。

  • v-for: 将此应用于您想要重复或迭代的元素。该指令需要一个名为 :key 的附加属性,以使其能够正确地进行响应式渲染;它可以像一个唯一的号码一样简单。

考虑一个示例,其中我们迭代列表元素五次。每个列表项将呈现其计数 (1, 2…5):

<ul><!-- do not apply v-for to this <ul> element -->
    <li v-for="n in 5" :key="n">{{ n }}</li>
</ul>

现在让我们看看一些基本指令是如何工作的。

练习 1.06:基本指令(v-text、v-once、v-html、v-bind、v-if、v-show)

更复杂的组件将使用多个指令来实现所需的结果。在本练习中,我们将构造一个组件,该组件使用多个指令来绑定、操作数据并将数据输出到模板视图。

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

  1. 打开命令行终端,导航到 Exercise1.06 文件夹,然后按顺序运行以下命令:

    > cd Exercise1.06/
    > code .
    > yarn
    > yarn serve
  2. 在 Exercise1-06.vue 中编写以下语法。这使用了我们在之前的练习中使用过的插值方法,此时您会非常熟悉该方法:

    <template>
        <div>
            <h1>{{ text }}</h1>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                // v-text
                text: 'Directive text',
            }
        },
    }
    </script>
    <style lang="scss" scoped>
    h2 {
        margin: 40px 0 0;
        font-weight: normal;
    }
    </style>
  3. 将插值替换为 v-text 属性。您会注意到输出不会改变:

    Figure 1.17 displays the output of the preceding code
    <template>
        <div>
            <h1 v-text="text">Loading...</h1>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                // v-text
                text: 'Directive text',
            }
        },
    }
    </script>
    image 2023 10 11 15 10 35 850
    Figure 1. Figure 1.17: The v-text directive output works very similarly to the interpolation method
  4. 在同一元素上添加 v-once 指令。这将强制此 DOM 元素仅加载 v-text 数据一次,只要它存在于页面中即可:

    <template>
        <div>
            <h1 v-once v-text="text">Loading...</h1>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                // v-text
                text: 'Directive text',
            }
        },
    }
    </script>
  5. h1 元素下,包含一个新的 h2 元素,该元素使用 v-html 属性。添加一个名为 html 的新数据键,其中包含一个具有 HTML 格式的字符串,如下所示:

    <template>
        <div>
            <h1 v-once v-text="text">Loading...</h1>
            <h2 v-html="html" />
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                // v-text
                text: 'Directive text',
                // v-html
                html: 'Stylise</br>HTML in<br/><b>your data</b>',
            }
        },
    }
    </script>

    运行前面的代码将生成如下输出:

    image 2023 10 11 15 15 35 715
    Figure 2. Figure 1.18: Output on rendering the HTML elements
  6. 将新的 link 对象添加到包含 URL、目标、标题和选项卡索引等一堆信息的 data 对象。在模板内,添加一个新的锚点 HTML 元素,并使用冒号语法将链接 data 对象绑定到 HTML 元素,例如 :href="link.url"

    <template>
        <div>
            <h1 v-once v-text="text">Loading...</h1>
            <h2 v-html="html" />
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                // v-text
                text: 'Directive text',
                // v-html
                html: 'Stylise</br>HTML in<br/><b>your data</b>',
            }
        },
    }
    </script>

    以下屏幕截图显示了输出:

    image 2023 10 11 15 18 42 077
    Figure 3. Figure 1.19: Output on binding the reactive data from the Vue instance to any HTML attribute
  7. v-if="false" 应用于 h1 元素,v-else-if="false" 应用于 h2,将 v-else 应用于 a 标签,如下所示:

    <template>
        <div>
            <h1 v-if="false" v-once v-text="text">Loading...</h1>
            <h2 v-else-if="false" v-html="html" />
            <a v-else
            :href="link.url"
            :target="link.target"
            :tabindex="link.tabindex"
            v-text="link.title"
            />
        </div>
    </template>

    您应该只在页面中看到 <a> 标记,因为我们已将条件语句设置为 false

    v-else 条件将显示如下:

    image 2023 10 11 15 23 34 812
    Figure 4. Figure 1.20: False v-if statements hiding the whole HTML element from the DOM
  8. 更改模板以使用 v-show 而不是 v-if 语句:

<template>
    <div>
        <h1 v-show="true" v-once v-text="text">Loading...</h1>
        <h2 v-show="false" v-html="html" />
        <a
        :href="link.url"
        :target="link.target"
        :tabindex="link.tabindex"
        v-text="link.title"
        />
    </div>
</template>

上述代码的输出如下:

image 2023 10 11 15 25 31 786
Figure 5. Figure 1.21: Changing v-show to true will display the element

当您打开浏览器开发工具的 Elements 选项卡时,您应该能够观察到 h2 显示状态设置为 none,如下所示:

image 2023 10 11 15 26 23 668
Figure 6. Figure 1.22: h2 displaying "display: none" for false condition

如果 v-show 结果为 true 布尔值,则 DOM 元素将保持原样。如果它解析为 false,它将对元素应用 display: none 样式。

在本练习中,我们了解了控制、绑定、显示和隐藏 HTML 模板元素的核心 Vue 指令,除了向本地状态添加新数据对象之外,不需要任何 JavaScript。

在下一节中,我们将学习如何借助 Vue 的 v-model 实现双向绑定。