Vue3 秘籍(五)
原文:
zh.annas-archive.org/md5/915E62C558C25E5846A894A1C2157B6C译者:飞龙
第八章:使用过渡和 CSS 为您的应用程序添加动画
为了使应用程序更加动态并吸引用户的全部注意力,使用动画是至关重要的。如今,CSS 动画出现在提示、横幅、通知甚至输入字段中。
有些情况下,您需要创建特殊的动画,称为过渡,并完全控制页面上发生的事情。为此,您必须使用自定义组件,并让框架帮助您渲染应用程序。
使用 Vue,我们可以使用两个自定义组件来帮助我们在应用程序中创建动画和过渡,这些组件是Transition和TransitionGroup。
在这一章中,我们将学习如何创建 CSS 动画,使用 Animate.css 框架创建自定义过渡,使用Transition组件钩子执行自定义函数,创建在组件渲染时执行的动画,为组和列表创建动画和过渡,创建可重用的自定义过渡组件,并在组件之间创建无缝过渡。
在这一章中,我们将涵盖以下内容:
-
创建你的第一个 CSS 动画
-
使用 Animate.css 创建自定义过渡类
-
使用自定义钩子创建交易
-
在页面渲染时创建动画
-
为列表和组创建动画
-
创建自定义过渡组件
-
在元素之间创建无缝过渡
技术要求
在这一章中,我们将使用Node.js和Vue-CLI。
注意 Windows 用户!您需要安装一个名为windows-build-tools的 NPM 包,以便能够安装以下所需的包。为此,请以管理员身份打开 PowerShell 并执行
> npm install -g windows-build-tools 命令。
要安装Vue-CLI,您需要打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows)并执行以下命令:
> npm install -g @vue/cli @vue/cli-service-global
创建基础项目
在这一章中,我们将使用此项目作为每个配方的基础。在这里,我将指导您如何创建基础项目:
- 打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows)并执行以下命令:
> vue create {replace-with-recipe-name}
- Vue-CLI 将要求您选择预设;使用空格键选择
手动选择功能:
? Please pick a preset: (Use arrow keys) default (babel, eslint) ❯ **Manually select features**
- 现在,Vue-CLI 将询问您希望安装哪些功能。您需要选择
CSS 预处理器作为默认功能之外的附加功能:
? Check the features needed for your project: (Use arrow keys) ❯ Babel
TypeScript Progressive Web App (PWA) Support Router Vuex ❯ CSS Pre-processors ❯ Linter / Formatter
Unit Testing E2E Testing
- 继续这个过程,选择一个 linter 和 formatter。在我们的情况下,我们将选择“ESLint + Airbnb 配置”:
? Pick a linter / formatter config: (Use arrow keys) ESLint with error prevention only ❯ **ESLint + Airbnb config** ESLint + Standard config
ESLint + Prettier
- 选择 linter 的附加功能。在我们的情况下,选择“保存时进行 lint”和“提交时进行 lint 和修复”:
? Pick additional lint features: (Use arrow keys) Lint on save ❯ Lint and fix on commit
- 选择要放置 linter 和 formatter 配置文件的位置。在我们的情况下,我们将选择“在专用配置文件中”:
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys) ❯ **In dedicated config files****In package.json**
- 最后,CLI 会询问您是否要保存未来项目的设置;选择
N。之后,Vue-CLI 将为您创建文件夹并安装依赖项:
? Save this as a preset for future projects? (y/N) n
- 从创建的项目中,打开位于
src文件夹中的App.vue文件。在单文件组件的<script>部分,删除HelloWorld组件。添加一个data属性,并将其定义为一个返回具有名为display的属性和默认值为true的 JavaScript 对象的单例函数:
<script> export default {
name: 'App',
data: () => ({
display: true,
}), }; </script>
- 在单文件组件的
<template>部分,删除HelloWorld组件,并添加一个带有文本Toggle的buttonHTML 元素。在imgHTML 元素中,添加一个绑定到display变量的v-if指令。最后,在buttonHTML 元素中,添加一个click事件。在事件监听器中,将值定义为一个将display变量设置为display变量的否定的匿名函数:
<template>
<div id="app">
<button @click="display = !display">
Toggle
</button>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png"> </div> </template>
有了这些说明,我们可以为本章中的每个示例创建一个基础项目。
创建您的第一个 CSS 动画
借助 CSS,我们可以在不需要手动通过 JavaScript 编程 DOM 元素的更改的情况下为我们的应用程序添加动画。使用专门用于控制动画的特殊 CSS 属性,我们可以实现美丽的动画和过渡效果。
要使用 Vue 中可用的动画,当将动画应用于单个元素时,我们需要使用一个名为Transition的组件,或者当处理组件列表时,需要使用一个名为TransitionGroup的组件。
在这个示例中,我们将学习如何创建一个 CSS 动画,并将此动画应用于 Vue 应用程序中的单个元素。
准备工作
以下是此示例的先决条件:
-
Node.js 12+
-
一个名为
cssanimation的 Vue-CLI 基础项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
使用基础项目,为这个示例创建一个名为cssanimation的新项目,并打开项目文件夹。现在,按照以下步骤进行操作:
- 打开
App.vue文件。在单文件组件的<template>部分中,使用Transaction组件包装imgHTML 元素。在Transaction组件中,添加一个name属性,其值为"image":
<transition name="image">
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png"> </transition>
- 在单文件组件的
<style>部分中,创建一个.image-enter-active类,其中包含一个值为bounce-in .5s的animation属性。然后,创建一个.image-leave-active类,其中包含一个值为bounce-in .5s reverse的animation属性:
.image-enter-active {
animation: bounce-in .5s; } .image-leave-active {
animation: bounce-in .5s reverse; }
- 最后,创建一个
@keyframes bounce-inCSS 规则。在其中,执行以下操作:
-
创建一个
0%规则,其中包含属性变换和值为scale(0)。 -
创建一个
50%规则,其中包含属性变换和值为scale(1.5)。 -
创建一个
100%规则,其中包含属性变换和值为scale(1):
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
} }
完成此操作后,当第一次按下切换按钮时,您的图像将放大并消失。再次按下时,动画完成后,图像将放大并保持正确的比例:
它是如何工作的...
首先,我们将 Vue 动画包装器添加到我们想要添加过渡效果的元素上,然后添加将在过渡中使用的 CSS 类的名称。
Transition组件使用预先制作的命名空间来要求必须存在的 CSS 类。这些是-enter-active,用于组件进入屏幕时,以及-leave-active,用于组件离开屏幕时。
然后,在<style>中创建 CSS 类,用于元素离开和进入屏幕的过渡,以及bounce-in动画的keyframe规则集,以定义其行为方式。
另请参阅
您可以在v3.vuejs.org/guide/transitions-overview.html#class-based-animations-transitions找到有关使用 Vue 类进行基于类的动画和过渡的更多信息。
您可以在developer.mozilla.org/en-US/docs/Web/CSS/@keyframes找到有关 CSS 关键帧的更多信息。
使用 Animate.css 创建自定义过渡类
在Transition组件中,可以定义在每个过渡步骤中使用的 CSS 类。通过使用此属性,我们可以使Transition组件在过渡动画中使用 Animate.css。
在这个示例中,我们将学习如何在组件中使用 Animate.css 类与Transition组件,以创建自定义过渡效果。
准备工作
以下是此示例的先决条件:
-
Node.js 12+
-
一个名为
animatecss的 Vue-CLI 基础项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
使用基础项目,为此示例创建一个名为animatecss的新项目,并打开项目文件夹。现在,按照以下步骤进行操作:
- 在项目文件夹中,打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows),并执行以下命令安装 Animate.css 框架:
> npm install animate.css@3.7.2
- 打开
src文件夹中的main.js文件并导入 Animate.css 框架:
import Vue from 'vue'; import App from './App.vue'; import 'animate.css';
- 打开
src文件夹中的App.vue文件,并将Transition组件添加为imgHTML 元素的包装器。在Transition组件中,添加一个名为enter-active-class的属性,并将其定义为"animated bounceInLeft"。然后,添加另一个名为leave-active-class的属性,并将其定义为"animated bounceOutLeft":
<transition
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutLeft" >
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png"> </transition>
完成此操作后,当第一次按下切换按钮时,您的图像将向左滑出并消失。再次按下时,它将从左侧滑入:
工作原理...
Transition组件最多可以接收六个属性,可以为交易的每个步骤设置自定义类。这些属性是enter-class、enter-active-class、enter-to-class、leave-class、leave-active-class和leave-to-class。在这个示例中,我们使用了enter-active-class和leave-active-class;这些属性定义了元素在屏幕上可见或离开屏幕时的自定义类。
为了使用自定义动画,我们使用了 Animate.css 框架,该框架提供了预先制作并准备好供使用的自定义 CSS 动画。我们使用了bounceInLeft和bounceOutLeft来使元素从屏幕中滑入和滑出。
还有更多...
您可以尝试更改enter-active-class和leave-active-class属性的类,以查看 CSS 动画在浏览器上的行为。
您可以在 Animate.css 文档中找到可用类的完整列表animate.style/。
另请参阅
您可以在v3.vuejs.org/guide/transitions-overview.html#class-based-animations-transitions找到有关基于类的动画和 Vue 类的过渡的更多信息。
您可以在animate.style/找到有关 Animate.css 的更多信息。
使用自定义钩子创建交易
Transaction组件具有每个动画生命周期的自定义事件发射器。这些可以用于附加自定义函数和方法,以在动画周期完成时执行。
我们可以使用这些方法在页面交易完成或按钮动画结束后执行数据获取,从而按特定顺序链接动画,这些动画需要根据动态数据依次执行。
在这个配方中,我们将学习如何使用Transaction组件的自定义事件发射器来执行自定义方法。
准备就绪
以下是此配方的先决条件:
-
Node.js 12+
-
名为
transactionhooks的 Vue-CLI 基础项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做到...
使用基础项目,为此配方创建一个名为transactionhooks的新项目,并打开项目文件夹。现在,按照以下步骤:
- 在项目文件夹中,打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows),并执行以下命令以安装 Animate.css 框架:
> npm install animate.css@3.7.2
- 在
src文件夹中打开main.js文件并导入 Animate.css 框架:
import Vue from 'vue'; import App from './App.vue'; import 'animate.css';
- 在
src文件夹中打开App.vue文件。在单文件组件的<script>部分,在数据属性中,在单例函数中,添加一个名为status的新属性,并将其值定义为"appeared":
data: () => ({
display: true,
status: 'appeared', }),
- 创建一个
methods属性,并将其定义为 JavaScript 对象。在对象内部,添加两个名为onEnter和onLeave的属性。在onEnter属性中,将其定义为一个函数,并在其中将数据status变量设置为"appeared"。在onLeave属性中,将其定义为一个函数,并在其中将数据status变量设置为"disappeared":
methods: {
onEnter() {
this.status = 'appeared';
},
onLeave() {
this.status = 'disappeared';
}, },
- 在单文件组件的
<template>部分,添加一个Transition组件作为imgHTML 元素的包装器。在Transition组件中,执行以下操作:
-
添加一个名为
enter-active-class的属性,并将其定义为"animated rotateIn"。 -
添加另一个名为
leave-active-class的属性,并将其定义为"animated rotateOut"。 -
添加事件监听器
after-enter绑定并将其附加到onEnter方法。 -
添加事件监听器
after-leave绑定并将其附加到onLeave方法:
<transition
enter-active-class="animated rotateIn"
leave-active-class="animated rotateOut"
@after-enter="onEnter"
@after-leave="onLeave" >
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png"> </transition>
- 创建一个
h1HTML 元素作为Transition组件的兄弟元素,并添加文本The image {{ status }}:
<h1>The image {{ status }}</h1>
现在,当点击按钮时,文本将在动画完成时更改。 它将显示动画完成后出现的图像和动画完成后消失的图像:
工作原理...
Transition组件有八个自定义钩子。 这些钩子由 CSS 动画触发,当它们被触发时,它们会发出自定义事件,可以被父组件使用。 这些自定义事件是before-enter,enter,after-enter,enter-cancelled,before-leave,leave,after-leave和leave-cancelled。
在使用after-enter和after-leave钩子时,当 CSS 动画完成时,屏幕上的文本会相应地更改为每个钩子的事件监听器上定义的函数。
另请参阅
您可以在v3.vuejs.org/guide/transitions-enterleave.html#javascript-hooks找到有关转换钩子的更多信息。
您可以在animate.style/找到有关 Animate.css 的更多信息。
在页面渲染时创建动画
在页面渲染时使用页面转换动画或自定义动画是常见的,有时需要引起应用程序用户的注意。
在 Vue 应用程序中可以创建此效果,无需刷新页面或重新渲染屏幕上的所有元素。 您可以使用Transition组件或TransitionGroup组件来实现这一点。
在本教程中,我们将学习如何使用Transition组件,以便在页面渲染时触发动画。
准备工作
本文档的先决条件如下:
-
Node.js 12+
-
一个名为
transactionappear的 Vue-CLI 基础项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
使用基础项目,为本教程创建一个名为transactionappear的新项目,并打开项目文件夹。 现在,按照以下步骤:
- 在项目文件夹中,打开 Terminal(macOS 或 Linux)或 Command Prompt/PowerShell(Windows),并执行以下命令以安装 Animate.css 框架:
> npm install animate.css@3.7.2
- 在
src文件夹中的main.js文件中导入 Animate.css 框架:
import Vue from 'vue'; import App from './App.vue'; import 'animate.css';
- 在
src文件夹中的App.vue文件中,为imgHTML 元素添加一个Transition组件作为包装器。在Transition组件中,执行以下操作:
-
添加一个名为
appear-active-class的属性,并将其定义为"animated jackInTheBox". -
添加一个名为
enter-active-class的属性,并将其定义为"animated jackInTheBox"。 -
添加另一个名为
leave-active-class的属性,并将其定义为"animated rollOut"。 -
添加
appear属性并将其定义为true:
<transition
appear
appear-active-class="animated jackInTheBox"
enter-active-class="animated jackInTheBox"
leave-active-class="animated rollOut" >
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png"> </transition>
页面打开时,Vue 标志将像一个爆米花盒一样摇晃,并在动画完成后保持静止:
工作原理...
Transition组件有一个特殊属性叫做appear,当启用时,使元素在屏幕上呈现时触发动画。该属性带有三个控制动画 CSS 类的属性,分别为appear-class、appear-to-class和appear-active-class。
还有四个与此属性一起执行的自定义钩子,分别为before-appear、appear、after-appear和appear-cancelled。
在我们的案例中,当组件在屏幕上呈现时,我们使组件执行 Animate.css 框架中的jackInTheBox动画。
另请参阅
您可以在v3.vuejs.org/guide/transitions-enterleave.html#transitions-on-initial-render找到有关初始渲染过渡的更多信息。
您可以在animate.style/找到有关 Animate.css 的更多信息。
为列表和组创建动画
有一些动画需要在一组元素或列表中执行。这些动画需要包装在TransitionGroup元素中才能工作。
该组件具有一些与Transition组件中相同的属性,但要使其工作,您必须为子元素和特定于该组件的组件定义一组特殊指令。
在此示例中,我们将创建一个动态图像列表,当用户点击相应按钮时将添加图像。这将在图像出现在屏幕上时执行动画。
准备工作
以下是此示例的先决条件:
-
Node.js 12+
-
一个名为
transactiongroup的 Vue-CLI 基础项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
使用基础项目,为此示例创建一个名为transactiongroup的新项目并打开项目文件夹。现在,按照以下步骤进行:
- 在项目文件夹中,打开 Terminal(macOS 或 Linux)或 Command Prompt/PowerShell(Windows),并执行以下命令来安装 Animate.css 框架:
> npm install animate.css@3.7.2
- 打开
src文件夹中的main.js文件并导入 Animate.css 框架:
import Vue from 'vue'; import App from './App.vue'; import 'animate.css';
- 打开
src文件夹中的App.vue文件。在单文件组件的<script>部分中,在data单例上返回一个名为count且值为0的属性:
data: () => ({
count: 0, }),
- 在单文件组件的
<template>部分中,删除div#appHTML 元素内的所有内容。然后,作为div#appHTML 元素的子元素,创建一个带有tag属性定义为"ul"和enter-active-class属性定义为"animated zoomIn"的TransitionGroup组件:
<div id="app">
<transition-group
tag="ul"
enter-active-class="animated zoomIn"
></transition-group>
</div>
- 作为
TransitionGroup组件的子元素,创建一个带有v-for指令的liHTML 元素,对count变量进行迭代,定义一个名为key的变量属性,其值为i,并定义一个style属性,其值为"float: left"。作为liHTML 组件的子元素,创建一个带有src属性定义为"https://picsum.photos/100"的imgHTML 组件:
<li
v-for="i in count"
:key="i"
style="float: left" >
<img src="https://picsum.photos/100"/> </li>
- 然后,作为
TransitionGroup组件的兄弟元素,创建一个带有style属性定义为"clear: both"的hrHTML 元素:
<hr style="clear: both"/>
- 最后,作为
hrHTML 元素的兄弟,创建一个带有click事件的buttonHTML 元素,将1添加到当前的count变量,并将文本设置为Increase:
<button
@click="count = count + 1" >
Increase
</button>
现在,当用户点击相应的按钮以增加列表时,它将向列表添加一个新项目,并触发放大动画:
它是如何工作的...
TransitionGroup元素通过tag属性中声明的标记创建一个包装器元素。这将通过检查子元素的唯一键来管理将触发动画的自定义元素。因此,TransitionGroup组件内的所有子元素都需要声明一个key并且必须是唯一的。
在我们的案例中,我们使用ul和li HTML 元素创建了一个 HTML 列表,其中TransitionGroup是使用ul标签定义的,子元素是使用li HTML 元素定义的。然后,我们对数字进行了虚拟迭代。这意味着将有一个项目列表,并根据该列表上的项目数量在屏幕上显示图像。
为了增加我们的列表,我们创建了一个button HTML 元素,每次按下时都会将count变量的计数增加一。
另请参阅
您可以在v3.vuejs.org/guide/transitions-list.html#reusable-transitions找到有关转换组的更多信息。
您可以在animate.style/找到有关 Animate.css 的更多信息。
创建自定义过渡组件
使用框架创建应用程序很好,因为您可以创建可重用的组件和可共享的代码。使用这种模式对简化应用程序的开发非常有帮助。
创建可重用的过渡组件与创建可重用组件相同,可以使用更简单的方法,因为它可以与函数渲染一起使用,而不是正常的渲染方法。
在本教程中,我们将学习如何创建一个可在我们的应用程序中使用的可重用的函数组件。
准备工作
本章的先决条件如下:
-
Node.js 12+
-
一个名为
customtransition的 Vue-CLI 基本项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
使用基本项目,为本教程创建一个名为customtransition的新项目,并打开项目文件夹。现在,按照以下步骤进行操作:
- 在项目文件夹中,打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows),并执行以下命令来安装 Animate.css 框架:
> npm install animate.css@3.7.2
- 在
src文件夹中的main.js文件中导入 Animate.css 框架:
import Vue from 'vue'; import App from './App.vue'; import 'animate.css';
- 在
src/components文件夹中创建一个名为CustomTransition.vue的新文件,并打开它。在单文件组件的<template>部分,添加functional属性以启用组件的函数渲染。然后,创建一个Transition组件,将appear变量属性定义为props.appear。将enter-active-class属性定义为"animated slideInLeft",将leave-active-class属性定义为"animated slideOutRight"。最后,在Transition组件内部,添加一个<slot>占位符:
<template functional>
<transition
:appear="props.appear"
enter-active-class="animated slideInLeft"
leave-active-class="animated slideOutRight"
>
<slot />
</transition> </template>
- 在
src文件夹中的App.vue文件中打开。在单文件组件的<script>部分,导入新创建的CustomTransition组件。在 Vue 对象上,添加一个名为components的新属性,将其定义为 JavaScript 对象,并添加导入的CustomTransition组件:
<script> import CustomTransition from './components/CustomTransition.vue'; export default {
name: 'App',
components: {
CustomTransition,
}, data: () => ({
display: true,
}), }; </script>
- 最后,在单文件组件的
<template>部分,使用CustomTransition组件包装imgHTML 元素:
<custom-transition>
<img
v-if="display"
alt="Vue logo" src="./assets/logo.png"> </custom-transition>
使用这个自定义组件,可以在不需要在组件上重新声明Transition组件和过渡 CSS 类的情况下重用过渡:
它是如何工作的...
首先,我们使用函数组件方法创建了一个自定义组件,不需要声明单文件组件的<script>部分。
在这个自定义组件中,我们使用Transaction组件作为基础组件。然后,我们使用注入的函数上下文prop.appear定义了appear属性,并为过渡添加了动画类,使其在组件呈现时从左侧滑入,销毁时从右侧滑出。
然后,在主应用程序中,我们使用这个自定义组件来包装img HTML 元素,并使其作为Transition组件工作。
另请参阅
您可以在v3.vuejs.org/guide/transitions-list.html#reusable-transitions找到有关可重用过渡组件的更多信息。
您可以在animate.style/找到有关 Animate.css 的更多信息。
在元素之间创建无缝过渡
当两个组件之间有动画和过渡时,它们需要是无缝的,这样用户在将组件放置在屏幕上时就看不到 DOM 抖动和重绘。为了实现这一点,我们可以使用Transition组件和过渡模式属性来定义过渡的方式。
在这个示例中,我们将使用Transition组件和过渡模式属性来创建图像之间的过渡动画。
准备工作
本章的先决条件如下:
-
Node.js 12+
-
一个名为
seamlesstransition的 Vue-CLI 基础项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
使用基础项目,为这个示例创建一个名为seamlesstransition的新项目,并打开项目文件夹。现在,按照以下步骤进行操作:
- 在
src文件夹中打开App.vue文件。在单文件组件的<style>部分,创建一个名为.rotate-enter-active,.rotate-leave-active的属性,并将transitionCSS 样式属性定义为transform .8s ease-in-out;。然后,创建一个名为.rotate-enter,.rotate-leave-active的属性,并将transformCSS 样式属性定义为rotate( -180deg );,并将transition定义为.8s ease-in-out;:
.rotate-enter-active, .rotate-leave-active {
transition: transform .8s ease-in-out; } .rotate-enter, .rotate-leave-active {
transform: rotate( -180deg );
transition: transform .8s ease-in-out; }
- 在单文件组件的
<template>部分,用Transition组件包裹imgHTML 元素。然后,将name属性定义为rotate,mode属性定义为out-in:
<transition
name="rotate"
mode="out-in" ></transition>
- 在
Transition组件中,对imgHTML 元素添加一个key属性,并将其定义为up。然后,添加另一个imgHTML 元素并添加一个v-else指令。添加一个key属性并将其定义为down,添加一个src属性并将其定义为"./assets/logo.png",最后添加一个style属性并将其定义为"transform: rotate(180deg)":
<img
v-if="display"
key="up"
src="./assets/logo.png"> <img
v-else
key="down"
src="./assets/logo.png"
style="transform: rotate(180deg)" >
当用户切换元素时,将执行离开动画,然后在完成后,进入动画将立即开始。这样就可以实现旧元素和新元素之间的无缝过渡:
它是如何工作的...
Transition组件有一个特殊的属性叫做mode,在这里可以定义元素过渡动画的行为。这种行为将创建一组规则,控制动画步骤在Transition组件内部的发生方式。在组件中可以使用"in-out"或"out-in"模式:
-
在
"in-out"行为中,新元素的过渡将首先发生,当它完成后,旧元素的过渡将开始。 -
在
"out-in"行为中,旧元素的过渡将首先发生,然后新元素的过渡将开始。
在我们的案例中,我们创建了一个动画,将 Vue 标志旋转到倒置状态。然后,为了处理这个无缝的变化,我们使用了"out-in"模式,这样新元素只会在旧元素完成过渡后才会显示出来。
另请参阅
您可以在v3.vuejs.org/guide/transitions-enterleave.html找到有关过渡模式的更多信息。
第九章:使用 UI 框架创建漂亮的应用程序
使用 UI 框架和库是提高生产力并帮助应用程序开发的好方法。您可以更多地专注于代码,而不是设计。
学习如何使用这些框架意味着您知道这些框架的行为和工作原理。这将有助于您在将来开发应用程序或框架的过程中。
在这里,您将学习在创建用户注册表单和页面所需的所有组件时,使用框架的更多用法。在本章中,我们将学习如何使用 Buefy、Vuetify 和 Ant-Design 创建布局、页面和表单。
在本章中,我们将涵盖以下示例:
-
使用 Buefy 创建页面、布局和用户表单
-
使用 Vuetify 创建页面、布局和用户表单
-
使用 Ant-Design 创建页面、布局和用户表单
技术要求
在这一章中,我们将使用 Node.js 和 Vue-CLI。
注意 Windows 用户:您需要安装一个名为windows-build-tools的npm包。为此,请以管理员身份打开 PowerShell 并执行以下命令:
> npm install -g windows-build-tools
要安装Vue-CLI,您需要打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows)并执行以下命令:
> npm install -g @vue/cli @vue/cli-service-global
使用 Buefy 创建页面、布局和用户表单
Bulma 是最早用于快速原型设计和 Web 开发的框架之一,它不需要附加 JavaScript 库。所有需要编码的特殊组件都是使用框架的开发人员的责任。
随着 JavaScript 框架的出现和围绕 Bulma 框架创建的社区,为 Vue 创建了一个包装器。这个包装器承担了 JavaScript 组件开发的所有责任,并为开发人员提供了在其应用程序中使用 Bulma 框架的完整解决方案,而无需重新发明轮子。
在这个示例中,我们将学习如何在 Vue 中使用 Buefy 框架,以及如何创建布局、页面和用户注册表单。
准备工作
本示例的先决条件如下:
-
Node.js 12+
-
一个 Vue-CLI 项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何做...
要使用 Buefy 框架创建一个 Vue-CLI 项目,我们首先需要创建一个 Vue-CLI 项目,然后将 Buefy 框架添加到项目中。我们将把这个步骤分为四个部分:创建 Vue-CLI 项目,将 Buefy 框架添加到项目中,创建布局和页面,最后创建用户注册表单。
创建 Vue-CLI 项目
在这里,我们将创建用于此示例的 Vue-CLI 项目。这个项目将具有自定义设置,以便能够与 Buefy 框架一起工作:
- 我们需要打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows),并执行以下命令:
> vue create bulma-vue
- Vue-CLI 会要求您选择一个预设 - 选择
手动选择功能:
? Please pick a preset: (Use arrow keys) default (babel, eslint) ❯ Manually select features
- 现在 Vue-CLI 会要求选择功能,您需要在默认功能之上选择
CSS 预处理器作为附加功能:
? Check the features needed for your project: (Use arrow keys) ❯ Babel
TypeScript Progressive Web App (PWA) Support Router Vuex ❯ CSS Pre-processors ❯ Linter / Formatter Unit Testing E2E Testing
- 在这里,Vue-CLI 会询问您想要使用哪种 CSS 预处理器;选择
Sass/SCSS(使用 node-sass):
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys) Sass/SCSS (with dart-sass) ❯ Sass/SCSS (with node-sass) Less **Stylus**
- 继续这个过程,选择一个 linter 和格式化程序。在我们的情况下,我们将选择
ESLint + Airbnb配置:
? Pick a linter / formatter config: (Use arrow keys) ESLint with error prevention only ❯ ESLint + Airbnb config ESLint + Standard config
ESLint + Prettier
- 选择 linter 的附加功能(这里是
在提交时进行 Lint 和修复):
? Pick additional lint features: (Use arrow keys) Lint on save ❯ Lint and fix on commit
- 选择您想要放置 linter 和格式化程序配置文件的位置(这里是
在专用配置文件中):
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys) ❯ In dedicated config files **In package.json**
- 最后,Vue-CLI 会询问您是否要保存设置以供将来使用;您应该选择
N。之后,Vue-CLI 将为您创建文件夹并安装依赖项:
? Save this as a preset for future projects? (y/N) n
将 Buefy 添加到 Vue-CLI 项目中
要在 Vue 项目中使用 Bulma,我们将使用 Buefy UI 库。这个库是 Bulma 框架的一个包装器,并提供了所有原始框架可用的组件以及一些额外的组件来使用:
- 在为 Vue-CLI 项目创建的文件夹中,打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows),并执行以下命令:
> vue add buefy
- Vue-CLI 会询问您是否要选择一个样式来使用 Buefy;我们将选择
scss:
? Add Buefy style? (Use arrow keys)
none
css
❯ scss
- 然后,Vue-CLI 会询问您是否要包括 Material Design 图标;对于这个项目,我们不会使用它们:
? Include Material Design Icons? (y/N) n
- 现在 Vue-CLI 会询问您是否要包括 Font Awesome 图标;我们将把它们添加到项目中:
? Include Font Awesome Icons? (y/N) y
使用 Buefy 创建布局和页面
要创建一个页面,我们需要创建一个布局结构和页面的基本组件,比如页眉菜单、页脚和页面的主要部分。
创建页眉菜单组件
在我们的设计中,我们将有一个页眉菜单,其中包含链接和呼吁行动按钮的基本组合:
-
在
src/components文件夹中创建一个名为top-menu.vue的新文件并打开它。 -
在单文件组件的
<script>部分,我们将导出一个defaultJavaScript 对象,其中name属性定义为TopMenu:
<script> export default {
name: 'TopMenu', }; </script>
- 在单文件组件的
<template>部分,创建一个带有section类的sectionHTML 元素,并添加一个带有container类的子divHTML 元素:
<section class="section">
<div class="container">
</div>
</section>
- 现在,在
div.containerHTML 元素的子级中创建一个b-navbar组件,并添加一个具有命名插槽brand的template占位符组件作为子级。在其中,添加一个带有href属性定义为#的b-navbar-item组件,并添加一个imgHTML 元素作为子级:
<b-navbar>
<template slot="brand">
<b-navbar-item href="#">
<img src="https://raw.githubusercontent.com/buefy/buefy/dev
/static/img/buefy-logo.png"
alt="Lightweight UI components for Vue.js based on Bulma"
>
</b-navbar-item>
</template> </b-navbar>
- 在这个
template占位符之后,创建另一个具有命名插槽start的template占位符。在其中,创建两个带有href属性定义为#的b-navbar-item组件。作为同级组件,创建一个带有label属性定义为Info的b-navbar-dropdown组件。在这个组件中,添加两个带有href属性定义为#的b-navbar-item组件作为子级:
<template slot="start">
<b-navbar-item href="#">
Home
</b-navbar-item>
<b-navbar-item href="#">
Documentation
</b-navbar-item>
<b-navbar-dropdown label="Info">
<b-navbar-item href="#">
About
</b-navbar-item>
<b-navbar-item href="#">
Contact
</b-navbar-item>
</b-navbar-dropdown> </template>
- 最后,在
template中创建另一个具有命名插槽end的占位符。创建一个b-navbar-item组件作为子组件,tag属性定义为div,并在该组件的子级中添加一个带有buttons类的divHTML 元素。在divHTML 元素中,创建一个带有button is-primary类的aHTML 元素,以及另一个带有button is-light类的aHTML 元素:
<template slot="end">
<b-navbar-item tag="div">
<div class="buttons">
<a class="button is-primary">
<strong>Sign up</strong>
</a>
<a class="button is-light">
Log in
</a>
</div>
</b-navbar-item> </template>
创建英雄区组件
我们将创建一个英雄区组件。英雄组件是一个全宽的横幅,为用户提供页面上的视觉信息:
-
在
src/components文件夹中创建一个名为hero-section.vue的新文件并打开它。 -
在单文件组件的
<script>部分,我们将导出一个defaultJavaScript 对象,其中name属性定义为HeroSection:
<script> export default {
name: 'HeroSection', }; </script>
- 在单文件组件的
<template>部分,创建一个带有hero is-primary类的sectionHTML 元素,然后添加一个带有hero-body类的divHTML 元素作为子级:
<section class="hero is-primary">
<div class="hero-body">
</div>
</section>
- 在
div.hero-bodyHTML 元素内部,创建一个带有container类的子divHTML 元素。然后,添加一个带有title类的h1HTML 元素作为子级,以及一个带有subtitle类的h2HTML 元素:
<div class="container">
<h1 class="title">
user Registration
</h1>
<h2 class="subtitle">
Main user registration form
</h2> </div>
创建页脚组件
我们将在布局中使用的最终组件是页脚组件。这将显示为我们页面的页脚:
-
在
src/components文件夹中创建一个名为Footer.vue的新文件并打开它。 -
在单文件组件的
<script>部分,我们将导出一个defaultJavaScript 对象,其中name属性定义为FooterSection:
<script> export default {
name: 'FooterSection', }; </script>
- 在单文件组件的
<template>部分,创建一个带有footer类的footerHTML 元素,然后添加一个带有content has-text-centered类的divHTML 元素:
<footer class="footer">
<div class="content has-text-centered">
</div>
</footer>
- 在
div.contentHTML 元素内,创建一个pHTML 元素作为初始页脚行,并创建第二个pHTML 元素作为第二行:
<p>
<strong>Bulma</strong> by <a href="https://jgthms.com">Jeremy
Thomas</a>
| <strong>Buefy</strong> by
<a href="https://twitter.com/walter_tommasi">Walter
Tommasi</a> </p> <p>
The source code is licensed
<a href="http://opensource.org/licenses/mit-license.php">MIT</a>.
The website content is licensed
<a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">CC
BY NC SA 4.0</a>.
</p>
创建布局组件
为了创建布局组件,我们将使用所有创建的组件,并添加一个将容纳页面内容的插槽:
-
在
src文件夹中创建一个名为layouts的新文件夹,并创建一个名为Main.vue的新文件并打开它。 -
在单文件组件的
<script>部分,导入footer-section组件和top-menu组件:
import FooterSection from '../components/Footer.vue'; import TopMenu from '../components/top-menu.vue';
- 然后,我们将导出一个
defaultJavaScript 对象,其中name属性定义为Mainlayout,并定义components属性为导入的组件:
export default {
name: 'Mainlayout',
components: {
TopMenu,
FooterSection,
}, };
- 最后,在单文件组件的
<template>部分,创建一个带有子top-menu组件、一个slot占位符和footer-section组件的divHTML 元素:
<template>
<div>
<top-menu />
<slot/>
<footer-section />
</div> </template>
使用 Buefy 创建用户注册表单
现在我们要创建用户注册表单并制作最终页面。在这一步中,我们将把所有其他步骤的输出合并到一个页面中:
- 打开
src文件夹中的App.vue文件。在单文件组件的<script>部分,导入main-layout组件和hero-section组件:
import Mainlayout from './layouts/main.vue'; import HeroSection from './components/heroSection.vue';
- 然后,我们将导出一个
defaultJavaScript 对象,其中name属性定义为App,然后定义components属性为导入的组件。在 JavaScript 对象中添加data属性,包括name、username、password、email、phone、cellphone、address、zipcode和country属性:
export default {
name: 'App',
components: {
HeroSection,
Mainlayout,
},
data: () => ({
name: '',
username: '',
password: '',
email: '',
phone: '',
cellphone: '',
address: '',
zipcode: '',
country: '',
}), };
- 在单文件的
<template>部分,添加导入的main-layout组件,并将hero-section作为子组件添加:
<template>
<main-layout>
<hero-section/>
</main-layout>
</template>
- 在
hero-section组件之后,创建一个兄弟sectionHTML 元素,带有section类,并添加一个带有container类的子divHTML 元素。在这个divHTML 元素中,创建一个带有title is-3类的h1HTML 元素和一个兄弟hrHTML 元素:
<section class="section">
<div class="container">
<h1 class="title is-3">Personal Information</h1>
<hr/>
</div>
</section>
- 然后,创建一个带有
Name作为label的b-field组件,作为hrHTML 元素的兄弟,并添加一个带有v-model指令绑定到name的子b-input。对于email字段,做同样的操作,将label更改为Email,并将v-model指令绑定到email。在 email 的b-input中,添加一个定义为email的type属性:
<b-field label="Name">
<b-input
v-model="name"
/> </b-field> <b-field
label="Email" >
<b-input
v-model="email"
type="email"
/> </b-field>
- 创建一个带有
grouped属性的b-field组件作为b-field组件的兄弟。然后,作为子组件,创建以下内容:
-
一个带有
expanded属性和label定义为Phone的b-field组件。添加一个带有v-model指令绑定到phone和type为tel的子b-input组件。 -
一个带有
expanded属性和label定义为Cellphone的b-field组件。添加一个带有v-model指令绑定到cellphone和type为tel的子b-input组件:
<b-field grouped> <b-field
expanded
label="Phone"
>
<b-input
v-model="phone"
type="tel"
/>
</b-field>
<b-field
expanded
label="Cellphone"
>
<b-input
v-model="cellphone"
type="tel"
/>
</b-field> </b-field>
- 然后,创建一个带有
title is-3类的h1HTML 元素作为b-field组件的兄弟,并添加一个hrHTML 元素作为兄弟。创建一个带有label定义为Address的b-field组件,并添加一个带有v-model指令绑定到address的b-input组件:
<h1 class="title is-3">Address</h1> <hr/> <b-field
label="Address" >
<b-input
v-model="address"
/> </b-field>
- 创建一个
b-field组件作为b-field组件的兄弟,带有grouped属性。然后,作为子组件,创建以下内容:
-
一个带有
expanded属性和label定义为Zipcode的子b-field组件。添加一个带有v-model指令绑定到zipcode和type属性定义为tel的b-input组件。 -
一个带有
expanded属性和label定义为Country的子b-field组件。添加一个带有v-model指令绑定到country和type属性定义为tel的b-input组件:
<b-field grouped>
<b-field
expanded
label="Zipcode"
>
<b-input
v-model="zipcode"
type="tel"
/>
</b-field>
<b-field
expanded
label="Country"
>
<b-input
v-model="country"
/>
</b-field> </b-field>
- 然后,创建一个
h1HTML 元素作为b-field组件的同级元素,使用title is-3类,并添加一个hrHTML 元素作为同级元素。创建一个带有grouped属性的b-field组件。创建一个子b-field组件,带有expanded属性和label定义为username,并添加一个带有v-model指令绑定到username的b-input组件。对于Password输入,做同样的事情,将label更改为Password,在b-input组件中定义v-model指令绑定到password,并添加type属性为password:
<h1 class="title is-3">user Information</h1> <hr/> <b-field grouped>
<b-field
expanded
label="username"
>
<b-input
v-model="username"
/>
</b-field>
<b-field
expanded
label="Password"
>
<b-input
v-model="password"
type="password"
/>
</b-field> </b-field>
- 最后,创建一个
b-field组件作为b-field组件的同级元素,定义position属性为is-right和grouped属性。然后,创建两个带有control类的divHTML 元素。在第一个divHTML 元素中,添加一个buttonHTML 元素作为子元素,使用button is danger is-light类,而在第二个divHTML 元素中,创建一个带有button is-success类的子buttonHTML 元素:
<b-field
position="is-right"
grouped
>
<div class="control">
<button class="button is-danger is-light">Cancel</button>
</div>
<div class="control">
<button class="button is-success">Submit</button>
</div>
</b-field>
它是如何工作的...
首先,我们创建一个 Vue-CLI 项目,进行基本配置,并添加额外的 CSS 预处理器node-sass。然后,我们能够使用 Vue-CLI 和 Buefy 插件将 Buefy 框架添加到我们的项目中。使用 Buefy 框架,我们创建了一个布局页面组件,带有页眉菜单组件和页脚组件。
对于页面,我们使用 Bulma CSS 容器结构来定义我们的页面,并将用户注册表单放在默认的网格大小上。然后,我们添加了 hero 部分组件,用于页面标识,最后,我们创建了用户注册表单和输入。
这是最终项目正在运行的屏幕截图:
另请参阅
在bulma.io/找到有关 Bulma 的更多信息。
在buefy.org/找到有关 Buefy 的更多信息。
使用 Vuetify 创建页面、布局和用户表单
Vuetify 是 Vue 最知名的三个 UI 框架之一。基于 Google 的 Material Design,这个框架最初是由 John Leider 设计的,现在作为 Vue 生态系统中的首选 UI 框架,用于应用程序的初始开发。
在这个食谱中,我们将学习如何使用 Vuetify 创建一个布局组件包装器、一个页面和一个用户注册表单。
准备工作
此处的食谱先决条件如下:
-
Node.js 12+
-
一个 Vue-CLI 项目
所需的 Node.js 全局对象如下:
-
@vue/cli -
@vue/cli-service-global
如何操作...
我们将把这个教程分为四个主要部分。前两部分专门用于创建项目和安装框架,后两部分专门用于创建用户注册页面和创建所需组件。
创建 Vue-CLI 项目
要在 Vue-CLI 项目中使用 Vuetify,我们需要创建一个自定义的 Vue-CLI 项目,并预定义配置,以便充分利用框架和提供的样式选项:
- 我们需要在终端(macOS 或 Linux)或命令提示符/PowerShell(Windows)中执行以下命令:
> vue create vue-vuetify
- 首先,Vue-CLI 会要求你选择一个预设;使用空格键选择
手动选择特性:
? Please pick a preset: (Use arrow keys) default (babel, eslint) ❯ **Manually select features**
- 现在 Vue-CLI 会要求选择特性,你需要选择
CSS 预处理器作为默认特性之外的附加特性:
? Check the features needed for your project: (Use arrow keys) ❯ Babel
TypeScript Progressive Web App (PWA) Support Router Vuex ❯ CSS Pre-processors ❯ Linter / Formatter
Unit Testing E2E Testing
- 在这里,Vue-CLI 会问你想使用哪种
CSS 预处理器;选择Sass/SCSS(使用 node-sass):
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules
are supported by default): (Use arrow keys) Sass/SCSS (with dart-sass) ❯ **Sass/SCSS (with node-sass)** Less **Stylus**
- 继续这个过程,选择一个代码检查工具和格式化工具。在我们的情况下,我们将选择
ESLint + Airbnb配置:
? Pick a linter / formatter config: (Use arrow keys) ESLint with error prevention only ❯ **ESLint + Airbnb config** ESLint + Standard config
ESLint + Prettier
- 选择代码检查工具的附加特性(这里是
提交时进行代码检查和修复):
? Pick additional lint features: (Use arrow keys) Lint on save ❯ Lint and fix on commit
- 选择你想要放置代码检查工具和格式化工具配置文件的位置(这里是
在专用配置文件中):
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys) ❯ **In dedicated config files****In package.json**
- 最后,Vue-CLI 会问你是否要保存设置以供将来的项目使用;你会选择
N。之后,Vue-CLI 会为你创建一个文件夹并安装依赖项:
? Save this as a preset for future projects? (y/N) n
将 Vuetify 添加到 Vue-CLI 项目中
要在 Vue 项目中使用 Vuetify,我们将使用 Vue-CLI 插件安装框架:
- 在你创建 Vue-CLI 项目的文件夹中,打开终端(macOS 或 Linux)或命令提示符/PowerShell(Windows),执行以下命令:
> vue add vuetify
- Vue-CLI 会问你是否要选择安装预设。选择默认预设。然后,Vue-CLI 将完成在项目上安装框架:
? Choose a preset: (Use arrow keys)
❯ Default (recommended)
Prototype (rapid development)
Configure (advanced)
- 安装完成后,Vuetify 将配置项目内的文件以加载框架。现在你可以开始使用它了。
使用 Vuetify 创建布局
使用 Vuetify 作为 UI 框架,我们使用 Material Design 指南作为基础,因为通过使用 Material Design,我们可以遵循设计指南来创建我们的设计结构,这将意味着更具吸引力的结构。您可以在material.io/design/introduction#goals找到 Material Design 指南。
创建顶部栏组件
在这部分,我们将创建一个top-bar组件,该组件将用于我们页面的布局中:
-
在
src/components文件夹中,创建一个名为TopBar.vue的文件并打开它。 -
在单文件组件的
<script>部分,我们将导出一个具有name属性定义为TopBar的defaultJavaScript 对象:
<script> export default {
name: 'TopBar', }; </script>
- 在
<template>部分内,创建一个带有app,dark和dense属性定义为true,以及color属性定义为primary的v-app-bar组件:
<v-app-bar
color="primary" app
dark dense ></v-app-bar>
- 在组件内部,创建一个带有
click事件的事件监听器的v-app-bar-nav-icon组件,在按钮被点击时发送一个名为'open-drawer'的事件:
<v-app-bar-nav-icon
@click="$emit('open-drawer')" />
- 最后,作为
v-app-bar-nav-icon组件的兄弟,添加一个v-toolbar-title组件,其中包含页面或应用程序的标题:
<v-toolbar-title>Vue.JS 3 Cookbook - Packt</v-toolbar-title>
创建抽屉菜单组件
在 Material Design 应用程序中,我们有一个弹出在页面上方的抽屉菜单。当用户点击我们刚刚在TopBar组件中创建的按钮时,这个菜单将被打开:
-
在
src/components文件夹中,创建一个名为DrawerMenu.vue的文件并打开它。 -
在单文件组件的
<script>部分,我们将导出一个具有三个属性的defaultJavaScript 对象:
-
name属性,定义为DrawerMenu。 -
props属性,定义为一个 JavaScript 对象,具有一个名为value的属性。这个属性将是另一个 JavaScript 对象,具有type,required和default属性。type属性定义为Boolean,required属性定义为true,default属性定义为false。 -
data属性,作为返回 JavaScript 对象的单例函数。该对象将具有一个menu属性,我们将其定义为将要使用的菜单项数组。数组将包含具有name、link和icon属性的 Javascript 对象。第一个菜单项的name定义为Home,link定义为*#*,icon定义为mdi-home。第二个菜单项的name定义为Contact,link定义为#,icon定义为mdi-email。最后,第三个菜单项的name定义为Vuetify,link定义为#,icon定义为mdi-vuetify。
<script>
export default {
name: 'DrawerMenu',
props: {
value: {
type: Boolean,
required: true,
default: false,
},
},
data: () => ({
menu: [
{
name: 'Home',
link: '#',
icon: 'mdi-home',
},
{
name: 'Contact',
link: '#',
icon: 'mdi-email',
},
{
name: 'Vuetify',
link: '#',
icon: 'mdi-vuetify',
},
],
}),
};
</script>
- 在
<template>部分,创建一个v-navigation-drawer组件,其中value属性作为绑定到valueprops 的变量属性,app属性定义为true,并在click事件上添加事件监听器,发送一个'input'事件:
<v-navigation-drawer
:value="value"
app
@input="$emit('input', $event)" ></v-navigation-drawer>
- 创建一个带有
dense属性定义为true的v-list组件。作为子元素,创建一个v-list-item组件并定义以下内容:
-
v-for指令遍历menu项。 -
key属性与菜单项的index。 -
link属性定义为true。 -
在
v-list-item内部,创建一个带有VIcon子元素的v-list-item-action,内部文本为item.icon。 -
在
v-list-item-action的同级位置创建一个v-list-item-content组件,其中v-list-item-title作为子元素,内部文本为item.name:
<v-list dense>
<v-list-item
v-for="(item, index) in menu"
:key="index"
link>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>{{ item.name }}</v-list-item-
title>
</v-list-item-content>
</v-list-item>
</v-list>
创建布局组件
要创建布局组件,我们将使用所有创建的组件,并添加一个插槽来容纳页面内容:
-
在
src/components文件夹中,创建一个名为Layout.vue的新文件并打开它。 -
在单文件组件的
<script>部分,导入top-bar组件和drawer-menu组件:
import TopBar from './TopBar.vue'; import DrawerMenu from './DrawerMenu.vue';
- 然后,我们将导出一个
defaultJavaScript 对象,其中name属性定义为Layout,然后创建components属性并导入组件。最后,将data属性添加为返回 JavaScript 对象的单例函数,其中drawer属性的值定义为false:
export default {
name: 'Layout',
components: {
DrawerMenu,
TopBar,
},
data: () => ({
drawer: false,
}), };
- 在
<template>部分内,创建一个v-app组件。作为第一个子元素,添加top-bar组件,并在open-drawer事件监听器上添加事件监听器,将drawer数据属性更改为drawer属性的否定。然后,作为top-bar的同级,创建一个drawer-menu组件,其v-model指令绑定到drawer。最后,创建一个v-content组件,其中包含一个子<slot>元素:
<template>
<v-app>
<top-bar
@open-drawer="drawer = !drawer"
/>
<drawer-menu
v-model="drawer"
/>
<v-content>
<slot/>
</v-content>
</v-app> </template>
使用 Vuetify 创建用户注册表单
现在,布局组件准备好了,我们将创建用户注册表单。因为 Vuetify 在表单中内置了验证,我们将使用它来验证表单中的一些字段。
单文件组件
在这里,我们将创建单文件组件的<script>部分:
-
在
src文件夹中,打开App.vue文件并清空其内容。 -
导入
layout组件:
import Layout from './components/Layout.vue';
- 然后,我们将导出一个
defaultJavaScript 对象,其中name属性定义为App,然后定义导入组件的components属性。将computed和methods属性定义为空的 JavaScript 对象。然后创建一个data属性,定义为返回 JavaScript 对象的单例函数。在data属性中,创建以下内容:
-
一个
valid属性,其值定义为false; -
name,username,password,email,phone,cellphone,address,zipcode和country属性定义为空字符串:
export default {
name: 'App', components: {
Layout,
}, data: () => ({
valid: true,
name: '',
username: '',
password: '',
email: '',
phone: '',
cellphone: '',
address: '',
zipcode: '',
country: '',
}),
computed: {}, methods: {}, };
- 在
computed属性中,创建一个名为nameRules的属性;这个属性是一个返回数组的函数,其中包含一个匿名函数,该函数接收一个值并返回该值的验证或错误文本。对passwordRules和emailRules属性也做同样的操作。在emailRules属性中,向返回的数组中添加另一个匿名函数,该函数通过正则表达式检查值是否为有效的电子邮件,如果值不是有效的电子邮件,则返回错误消息:
computed: {
nameRules() {
return [
(v) => !!v || 'Name is required',
];
},
passwordRules() {
return [
(v) => !!v || 'Password is required',
];
},
emailRules() {
return [
(v) => !!v || 'E-mail is required',
(v) => /.+@.+\..+/.test(v) || 'E-mail must be valid',
];
}, },
- 最后,在
methods属性内,创建一个名为register的新属性,它是一个调用$refs.form.validate函数的函数。还创建另一个名为cancel的属性,它是另一个调用$refs.form.reset函数的函数:
methods: {
register() {
this.$refs.form.validate();
},
cancel() {
this.$refs.form.reset();
}, },