如何在 Vue.js 中使用内置指令和自定义指令

作者选择了 开源精神疾病以作为 写给捐赠计划的一部分获得捐赠。

介绍

作为前端框架, Vue.js可以被认为是 ReactAngular的混合物。Vue借用了 React 的 prop-driven 方法,但也使用了 directives,这些指令被 Angular 推广了。在这种情况下,指令是开发人员可以在 HTML模板中使用的可重复使用的代码或逻辑。这些可以让你以许多不同的方式操纵你的 HTML,例如有条件地渲染一个元素,将事件连接到一个元素,或创建取取决于你的Vue代码的动态属性。

在本教程中,您将尝试一些最常见的内置Vue指令,如v-if,v-show,v-on,v-bind,v-modelv-html。对于这些第一个部分,本教程将引导您通过例子,您可以在在线Vue玩场(如Vue单个文件组件播放场)(https://sfc.vuejs.org/)中遵循。

前提条件

使用v-if,v-elsev-else-if指令

Vue.js 预先包装了一些开发人员在框架内工作时通常使用的指南. 指南如v-if,v-show,v-on,v-model,v-bind,v-html等等,都为您提供外包。

v-ifv-elsev-else-if指令允许您创建条件渲染的HTML元素,并与JavaScript的if,else if,else条件相似地工作(https://andsky.com/tech/tutorials/how-to-write-conditional-statements-in-javascript)。

若要应用 Vue 指令,您将其添加到 Vue 单个文件组件模板部分中的 HTML 元素中。

1<p v-if="condition"></p>

在这种情况下,突出的条件是决定段元素是否被渲染的布尔式表达式的位数。

为了说明v-if指令在现实情况下是如何工作的,请为用户欢迎页面创建以下代码:

 1<template>
 2  <p v-if="user.firstName && user.lastName">
 3    Welcome, {{ user.firstName }} {{ user.lastName }}!
 4  </p>
 5  <p v-else-if="user.username">
 6    Welcome, {{ user.username }}!
 7  </p>
 8  <div v-else>
 9    <button>Login</button>
10    <button>Create Account</button>
11  </div>
12</template>
13
14<script setup>
15    const user = {
16    firstName: 'Sammy',
17    lastName: 'Shark',
18    username: 'sammyDO'
19  }
20</script>

在这个代码中,有许多HTML元素,包括两个<p>标签和一个具有两个按钮的<div>标签,但是,当这个代码在浏览器中运行时,只有其中一块代码会渲染,取决于评估为真实的条件。

正如现在所见,由于firstNamelastName都具有<script>标签中的值,因此user.firstName && user.lastName表达式将评估为true,浏览器将渲染段落。

Web page with the words "Welcome, Sammy Shark!"

如果未定义firstNamelastName,则条件将评估为false,而Vue将转移到v-else-if指令。本指令附加到user.username表达式,因此如果此评估为true,则将变成附加的段落元素。

1...
2<script setup>
3    const user = {
4    lastName: 'Shark',
5    username: 'sammyDO'
6  }
7</script>

由于条件user.firstName && user.lastName现在被评估为false,而user.username则被评估为true,因此用户名将返回。

Web page with the words "Welcome, sammyDO!"

最后,如果所有猜测评估为false,控制将转移到v-else指令中,此处返回两个按钮来登录或创建帐户。

1...
2<script setup>
3    const user = {
4    lastName: 'Shark',
5  }
6</script>

现在你会发现默认按钮在浏览器中渲染:

Web page with "Login" and "Create Account" buttons

重要的是要注意,您必须在v-if指令或v-else-if指令之前直接有v-if指令的元素。

例如,以下代码片段被认为是无效的,您会在浏览器的控制台中收到错误:

 1<template>
 2  <p v-if="user.firstName && user.lastName">
 3    Welcome, {{ user.firstName }} {{ user.lastName }}!
 4  </p>
 5  <p v-else-if="user.username">
 6    Welcome, {{ user.username }}!
 7  </p>
 8  <h1>Some Title</h1>
 9  <div v-else>
10    <button>Login</button>
11    <button>Create Account</button>
12  </div>
13</template>
14
15<script setup>
16    const user = {
17    firstName: 'Sammy',
18    lastName: 'Shark',
19    username: 'sammyDO'
20  }
21</script>

由于在v-else-if指令的段落之后的<h1>元素没有指令,这个代码将失效,并会产生以下语法错误:

1[secondary_label Output]
2SyntaxError: v-else/v-else-if has no adjacent v-if.

有了这个v-if的摘要,你现在可以尝试另一种条件显示HTML元素的方式:该v-show指令。

使用v-show指令

除了与v-if相关的指令之外,还有另一个指令可以用来显示基于条件的HTML元素. 该指令是v-show。 它类似于v-if,除非没有else-ifelse对应元素,而不是有条件渲染的元素。

看看以下代码,该代码解决了与上一节相似的情况:

 1<template>
 2  <div v-show="!userIsLoggedIn">
 3    <button>Login</button>
 4    <button>Create Account</button>
 5  </div>
 6  <div v-show="userIsLoggedIn">
 7    <p>Welcome!</p>
 8  </div>
 9</template>
10
11<script setup>
12    const userIsLoggedIn = true
13</script>

在此代码中,您已将v-show附加到两个<div>和条件表达式中。v-show将显示附加的HTML,如果引用标记中的条件满足。

Web page with the words "Welcome!"

现在将userIsLoggedIn值更改为false:

1...
2<script setup>
3    const userIsLoggedIn = false
4</script>

您将再次找到登录按钮:

Web page with "Login" and "Create Account" buttons

值得强调的是‘v-if’和‘v-show’之间的区别。‘v-if’有条件地渲染 HTML;如果条件式表达式评估为‘false’,则 DOM将不包括它。

随着条件v-ifv-show指令被覆盖,您现在可以转到v-on指令来将事件绑定到HTML元素。

使用v-on指令

v-on指令对特定的 事件执行函数。这可能是一个自定义事件或一个标准的JavaScript事件,例如click,hovermouseenter。当使用v-on指令时,您必须在一个(:)之后提供事件类型和要执行的函数。

作为一个例子,看看下面的突出代码:

1<template>
2  <button v-on:click="handleClick">Click Me</button>
3</template>
4
5<script setup>
6    function handleClick() {
7    alert('You clicked the button!')
8  }
9</script>

在本示例中,当用户点击指令附带的<按钮>元素时,组件函数handleClick将执行。

Browser popup box that reads "You clicked the button!"

具有v-on指令的事件也可以有 event modifiers 链接到事件本身. 这些事件修改器可以改变事件的执行方式,并在写作时节省时间,通常需要多个JavaScript行。

  • once: 限制事件只发射一次.
  • 自我: 事件只会触发,如果事件的目标是持有指令的相同元素。

接下来,您将通过一个例子一次事件修改器来尝试语法。

1<template>
2  <button v-on:click.once="handleClick">Click Me</button>
3</template>
4...

使用「.once」修改器,函數「handleClick」只會執行一次. 試著點擊「Click Me」按鈕,警告會出現. 清除警告,然後再點一下。

v-on指令也有一个短语语法. 要使用短语语法,用@代替v-on:

1<template>
2  <button @click.once="handleClick">Click Me</button>
3</template>
4...

这将导致与v-on:click.once相同的行为。

现在事件已被用v-on处理,您可以转到将数据绑定到使用v-bindv-model的模板元素。

使用v-bindv-model指令

Vue.js 是一个 Model-View-ViewModel (MVVM)]框架,这意味着单独的数据(模型)更新了 HTML (视图),视图反过来更新了模型。

为了启用 MVVM 方法,Vue 提供了将数据、代理和计算属性传输到 Vue 组件的途径,这是通过 two-way data binding 进行的,这允许视图和模型相互作用。

在下面的代码中,你有一个具有动态内容的 <p> 元素,该元素根据数据值而变化:

1<template>
2  <p>I am from {{ city }}.</p>
3</template>
4
5<script setup>
6    const city = 'Cincinnati'
7</script>

在此片段中,城市城市元素之后的 <script>元素中的常数的数据引用,因为现在,城市将评估到辛辛那提字符串,并在您的浏览器中呈现一个含有我来自辛那提字符的段落元素。

对于这种动态内容,您不需要使用指令: 模板可以自动访问城市常数,但是,如果您想通过引用<script>数据来使 HTML 属性动态,则必须用v-bind来明确绑定数据。

为了说明这一点,您将在链接(<a>)标签中插入城市定位标签,该标签将动态地引导到城市定位的城市的 维基百科页面。 首先,将城市定位标签嵌入城市定位标签中,以便用户可以点击它并获取更多关于城市本身的信息。 之后,创建一个名为wikipediaLink的计算属性,并让它返回适当的 URL。 添加突出的代码:

 1<template>
 2  <p>I am from <a href="">{{ city }}</a>.</p>
 3</template>
 4
 5<script setup>
 6  import { computed } from 'vue'
 7
 8    const city = 'Cincinnati'
 9  const wikipediaLink = computed(() =>`https://en.wikipedia.org/wiki/${city}`)
10</script>

<script>元素中,您从视图库中导入了计算函数,然后使用它将 URL 分配给wikipediaLink

现在你有你的维基百科链接,继续,并将计算的属性名称添加到你之前添加的标的href属性:

1<template>
2  <p>I am from <a href="wikipediaLink">{{ city }}</a>.</p>
3</template>
4...

如果你在这个时候在浏览器中看到这个,你会收到一个控制台错误,这是因为Vue.js现在认为‘wikipediaLink’是一个字符串,而不是一个有效的URL。

要告诉 Vue.js 使用wikipediaLink计算属性的返回值,您需要使用v-bind指令。

1<template>
2  <p>I am from <a v-bind:href="wikipediaLink">{{ city }}</a>.</p>
3</template>
4...

现在,href值将是辛辛那提维基百科页面的URL,如果城市属性更改到另一个城市,如西雅图,这个URL将更新。

v-on类似,v-bind也有你可以选择使用的短语,如下所示,用v-bind:替换短语:

1<template>
2  <p>I am from <a :href="wikipediaLink">{{ city }}</a>.</p>
3</template>

Vue.js 中有另一个指令用于将值绑定到一个数据属性,但此指令仅适用于输入标签:

1<template>
2  <input v-model="city" type="text" />
3</template>
4
5<script setup>
6  const city = 'Cincinnati'
7</script>

当使用v 模型指令时,您将输入字段属性绑定到引用标记中的数据属性。

此 Vue 组件将显示一个文本输入框,默认文本为 Cincinnati,如下图所示:

Text input box with "Cincinnati" set as the default text.

本节涵盖了将HTML属性绑定到变量或计算数据的不同方式,接下来,您将使用v-html指令将HTML注入您的模板。

使用v-html指令

本教程将讨论的最后一个预先包装的指令是v-html。本指令将字符串中的HTML转换为原始HTML,浏览器可以阅读,这将允许您在创建和应用HTML的方式上更灵活。

在这个假设的组件中,你有一个<div>,它有一个v-html指令,其值为数据属性:

1<template>
2  <div v-html="someHtmlCode" />
3</template>
4
5<script setup>
6  const someHtmlCode = `<p>Some <span>HTML</span> in this string</p>`
7</script>

v-html指令是指示Vue.js将someHtmlCode数据引用链接注入模板中的<div />

1<div>
2  <p>Some <span>HTML</span> in this string</p>
3</div>

HTML也會在您的瀏覽器中顯示:

A browser window with "Some HTML in this string" rendered on the screen

如果您需要将来自 REST API 服务的 HTML 或来自外部 JavaScript 文件的大型 HTML 渲染,则此指令很有用。

在本教程的这一点上,你已经尝试了Vue.js为你提供的指令,但是,有时你可能需要Vue不提供的指令,在这种情况下,你可以创建一个自定义指令来处理HTML模板中的特定逻辑。

创建一个定制指令

在 Vue.js 框架中,您可以创建自定义指令,以满足您项目的个别需求,例如,在本节中,您将创建一个v-theme指令,将特定风格应用于您的模板元素。

到目前为止,您不必跟随一个独立的Vue项目,但是,在本节中,您将创建从Vue CLI生成的新项目。

打开终端并使用以下命令生成一个新项目,该项目的名称将是自定义指令,这也将是根目录的名称:

1vue create custom-directive

对于本教程,选择Vue 3xChoose Vue Version。一旦应用程序已经创建,请在您所选择的文本编辑器中打开生成的项目,然后在src目录中打开main.js文件。

將「createApp(App)」儲存為「const」,以便您稍後可以參考它:

1[label custom-directive/src/main.js]
2import { createApp } from 'vue'
3import App from './App.vue'
4
5const app = createApp(App)
6
7app.mount('#app')

现在,有了自己的const中的createApp功能,您可以通过添加指令来扩展此应用程序:

1[label custom-directive/src/main.js]
2import { createApp } from 'vue'
3import App from './App.vue'
4
5const app = createApp(App)
6
7app.directive("theme", {})
8
9app.mount('#app')

在此代码中,您正在利用 Vue 实例中的 directive() 函数. 此函数接受两个参数:指令名称 (在这种情况下, theme) 和具有 [lifecycle hooks] 的对象(https://v3.vuejs.org/api/options-lifecycle-hooks.html)。

您将设置此代码,以便在组件安装时执行。 此安装链接接受两种参数: el 是 HTML 元素和 binding 是指令中传输的值。

 1[label custom-directive/src/main.js]
 2const app = createApp(App)
 3
 4app.directive("theme", {
 5  mounted(el, binding) {
 6
 7  }
 8})
 9
10app.mount('#app')

对于这个主题指令,你将通过一个字符串来确定元素的风格. 这个字符串将是主要,次要三级,每个字符串都与假设的色彩方案中的颜色相匹配。

现在指令代码已经到位,您可以添加逻辑。 要访问指令的引数标记中的值,您可以使用binding.value。 要更改元素的文本颜色,您将使用JavaScript访问el属性:

 1[label custom-directive/src/main.js]
 2const app = createApp(App)
 3
 4app.directive("theme", {
 5  mounted(el, binding) {
 6    if (binding.value === 'primary') {
 7      el.style.color = 'red'
 8    } else if (binding.value === 'secondary') {
 9      el.style.color = 'green'
10    } else if (binding.value === 'tertiary') {
11      el.style.color = 'blue'
12    } else {
13      el.style.color = 'black'
14    }
15  }
16})
17
18app.mount('#app')

该片段的突出部分是一系列的如果/else陈述. 如果指令中传输的值为主要,文本颜色将是红色,次要将是绿色,三级将是蓝色,没有值会返回默认黑色

关闭并保存您的main.js文件。

在此时,您已经创建了一个自定义指令,您可以在 Vue.js 应用程序中使用。

在您选择的文本编辑器中打开您的App.vue文件. 在模板中,添加一个<p>标签,其中包含一些文本:

1[label custom-directive/src/App.vue]
2<template>
3  <p>This text will change color based on the directive value!</p>
4</template>

保存此檔案,然後用「npm run server」啟動應用程式. 這將在您的「localhost」上的「:8080」端口執行您的項目:

1npm run serve

要查看您生成的项目,请打开您所选择的浏览器,并访问URL栏中的localhost:8080

The words "This text will change color based on the directive value!" rendered in default black text.

接下来,通过将您的指令添加到 HTML 来更改颜色:

1[label custom-directive/src/App.vue]
2<template>
3  <p v-theme="`primary`">This text will change color based on the directive value!</p>
4</template>

保存此文件并在您的 Web 浏览器中打开它. 引文标记中的值是一个原始值,并且自动绑定到 Vue,所以在引文标记中,您需要使用回头标记将其转换为字符串。

保存您的文件,您的渲染网站上的文本将变成红色:

The words "This text will change color based on the directive value!" rendered in red text.

该指令会读取绑定对象中的值并相应地执行代码. 由于该值是主要,JavaScript 会将文本的颜色改变为红色。

在本节中,您创建了自定义指令,注册了它,并执行了其逻辑,您还添加了新的自定义指令,并将其分配到模板中的 HTML 元素中。

结论

在本教程中,您通过练习来测试指令是什么以及如何使用它们。具体来说,您使用了最常见的内置指令,包括v-if,v-on,v-showv-html。此外,您注册并创建了自己的自定义指令。

虽然您已经通过了一些指南,但Vue.js为您提供了许多更多指南. 有关指南的更多信息,建议您查看官方 Vue.js 文档. 有关Vue的更多教程,请参阅 如何使用Vue.js 开发网站系列页面

Published At
Categories with 技术
comments powered by Disqus