如何使用 Vue.js、Vuex、Vuetify 和 Firebase 构建单页应用程序(第 1 部分,共 4 部分)

2025-05-26

如何使用 Vue.js、Vuex、Vuetify 和 Firebase 构建单页应用程序(第 1 部分,共 4 部分)

了解如何使用 Vue.js、Vuex、Vue Router 和 Firebase 创建送餐网站。

你想学习如何使用 Vue.js 吗?想用 Vue.js 创建一个逼真的网站吗?在本教程中,我将教你如何使用 Vue、Vuex、Vue Router、Vuetify 和 Firebase 创建一个送餐网站。

本教程将以一系列文章的形式呈现,带您从首次安装 Vue 开始,到创建一个功能齐全的送餐网站。上方标题图片展示了我们将要创建的网站。

本教程分为四个部分。以下是每个部分的链接:

第 1 部分:安装 Vue 并使用 Vuetify 和 Vue Router 构建 SPA

第 2 部分:使用 Vue Router

第 3 部分:使用 Vuex 并访问 API

第 4 部分:使用 Firebase 进行身份验证

本教程适合所有人,无论您的技能水平如何。我假设您已经了解 ES6。

让我们开始吧。

安装 Vue

使用 Vue.js 创建新应用程序是通过其命令行界面 (CLI) 完成的。您需要先使用以下命令安装 CLI:


 install -g @vue/cli

Enter fullscreen mode Exit fullscreen mode

-g 标志告诉 npm 全局安装 CLI。安装完成后,可以在终端中使用命令vue来访问 CLI。运行此命令将显示可用的命令:

Vue 命令选项。

注意: 如果您读过有关 Vue 的其他文章,您可能会看到他们讨论使用以下命令安装 CLI:


 install -g vue-cli

Enter fullscreen mode Exit fullscreen mode

这样就安装了旧版本的 Vue CLI。在撰写本教程时,Vue CLI 的当前版本是 3。要安装最新版本,请使用我给出的第一个命令。

创建我们的膳食准备应用程序

现在我们已经安装了 CLI,下一步是为我们的 Vue 应用程序创建脚手架。在终端输入以下命令:


 create meal-prep

Enter fullscreen mode Exit fullscreen mode

Vue CLI 会询问一系列问题,以确定如何搭建你的应用程序。在第一个提示符下,你需要选择“手动选择功能”。

创建 Vue 应用程序时手动选择功能。

接下来,我们将被要求选择要为应用程序安装的功能。在本教程中,请选择 Babel、Router、Vuex 和 Linter/Formatter。

向我们的应用程序添加 Babel、Router、Vuex 和 Linter

接下来,您将被问到一系列问题。

对于 linter,我选择了Prettier并选择了“保存时进行 Lint”。我选择了将配置文件放在我的 package.json 文件中,而不是放在单独的配置文件中。

以下是我选择的选项:

为 Vue 应用程序选择的选项

Vue CLI 将使用你选择的功能构建我们的应用程序。由于我指定要创建一个名为“meal-prep”的应用程序,因此它将创建一个以此名称命名的新文件夹。

一旦 CLI 成功创建了应用程序,它将为您提供更改到新创建的目录的命令以及启动应用程序所需运行的命令:

Vue CLI 成功创建了我们的应用程序。

启动我们的应用程序

要启动我们的应用程序,我们需要进入meal-prep目录并运行命令npm run serve。我们的应用程序如下所示:

默认 Vue 应用程序。

Vue 为我们搭建了一个 SPA 应用,并安装了 Vue Router 和 Vuex。点击页面顶部菜单中的“关于”按钮,我们可以看到 Vue Router 的运行情况。这将加载“关于”页面。

关于我们的应用程序的页面。

添加 Vuetify

Vuetify 是一个 Material Design 组件框架,类似于 Bootstrap。Vuetify 提供了 80 多个 Material Design 组件,可用于在 Vue 中设置 SPA 样式。要将 Vuetify 添加到我们的应用程序中,首先,打开终端并停止服务器。然后使用以下命令将 Vuetify 添加到我们的应用程序中:


 add vuetify

Enter fullscreen mode Exit fullscreen mode

你会被问到一系列问题。我将选择不使用预制模板,因为我想保留默认 Vue 应用程序创建的结构。其余问题我都选择了默认设置。以下是我对这些问题的回答:

安装 Vuetify 时选择的选项。

配置 Prettier

在创建 Vue 应用程序时,我选择使用 Prettier 进行代码检查。我还选择在 package.json 文件中安装配置设置。现在我想花点时间配置 Prettier,使其使用我的首选设置。

在代码编辑器中打开 package.json 文件。在此文件中,您将看到为 eslint 创建的默认设置。在 eslintConfig 对象之后、postcss 对象之前,我将添加一些设置来配置 Prettier。我将缩进设置为 4 个空格,并使用单引号。(注意:如果您喜欢缩进 2 个空格和/或使用双引号,则无需添加此更改。)

这是我添加到 package.json 文件中的 Prettier 设置:

package.json 文件中的配置更漂亮。

接下来,我想重新配置所有文件以使用新的 Prettier 设置。这意味着要将所有缩进从 2 个空格改为 4 个空格,并将双引号改为单引号。幸运的是,Vue 提供了一个 lint 脚本,可以自动帮我修复所有这些问题。

从终端运行此命令:


 run lint

Enter fullscreen mode Exit fullscreen mode

这将检查所有文件,并将它们更改为我的新 Prettier 设置。此命令将列出所有已自动修复的文件。

Lint 自动为我们修复了所有文件。

设计应用程序的主页

我们将使用 Vuetify 来设计我们的应用程序。您可以在这里找到有关 Vuetify 提供的所有 UI 组件的更多详细信息。所有使用 Vuetify 的应用程序都必须使用 进行包装<v-app>。打开 App.vue 文件并删除模板中的所有代码和所有样式。您的 App.vue 应该如下所示:



<template>
    <v-app>
        <v-content transition="slide-x-transition">
            <router-view></router-view>
        </v-content>
    </v-app>
</template>

<script>
export default {
    name: 'App'
};
</script>

<style>
</style>


Enter fullscreen mode Exit fullscreen mode

这段代码将我们的应用程序包装在<v-app>Vuetify 所需的标签中。该标签内是<v-content>标签。 里面是<router-view>标签。路由器视图标签将显示您当前所在的页面。当我们在主页时,它将显示主页视图。当我们导航到关于页面时,它将显示关于视图。

创建主页

接下来打开位于 views 文件夹中的 Home.vue 文件。我们将删除其中的代码。删除模板中的所有内容。删除 HelloWorld 的 import 命令和注释。删除 components 对象。以下是我们将要创建的主页内容:

膳食准备应用程序的主页

应用程序导航

我们首先要做的事情是导航。我将创建一个新的 Vue 组件用于导航。在 components 文件夹中创建一个名为AppNavigation.vue的新文件。

我们的导航必须适应多种不同的屏幕尺寸。在笔记本电脑或台式机等大屏幕上,我们会在屏幕顶部显示一个菜单。在手机等小屏幕上,我们会显示传统的汉堡菜单图标。当用户点击该图标时,一个包含菜单的抽屉会从左侧滑入。该抽屉会一直显示在网站顶部,直到用户关闭它。

Vuetify 提供了两种工具来显示不同屏幕尺寸的菜单。对于中型和大型屏幕,我们将使用 Vuetify<v-toolbar>组件。在较小的屏幕上,我们将显示<v-navigation-drawer>组件。

让我们首先为新的 Vue 组件搭建默认配置。AppNavigation.vue 文件应包含以下代码:



<template>

</template>

<script>
export default {
    name: 'AppNavigation'
};
</script>

<style scoped>
</style>


Enter fullscreen mode Exit fullscreen mode

我们将首先创建一个在中大屏幕尺寸上显示的菜单。为此,我们将使用<v-toolbar>组件。以下是您将要输入的导航代码:



<template>
        <v-toolbar app color="brown darken-4" dark>
            <v-toolbar-side-icon></v-toolbar-side-icon>
            <v-toolbar-title>{{appTitle}}</v-toolbar-title>
            <v-btn flat>Menu</v-btn>
            <v-spacer></v-spacer>
            <v-btn flat>SIGN IN</v-btn>
            <v-btn color="brown lighten-3">JOIN</v-btn>
        </v-toolbar>
</template>

<script>
export default {
    name: 'AppNavigation'
};
</script>

<style scoped>
</style>


Enter fullscreen mode Exit fullscreen mode

此代码将生成此菜单:

菜单工具栏

让我解释一下我在菜单中使用的项目。<v-toolbar>我添加了app属性。此属性将组件指定为应用程序布局的一部分。它用于动态调整内容大小。当侧边抽屉滑出时,屏幕上的内容将相应调整。

接下来,我为导航栏添加了颜色。Vuetify 提供了对 Material Design 规范中所有颜色的访问。这些值可以通过颜色类系统在样式表、组件文件以及实际组件中使用。我选择了 darken-4 变体的棕色作为导航栏颜色。以下是 Vuetify 提供的所有颜色

工具栏上有许多辅助组件可供使用。其中一个辅助组件是工具栏侧边图标。这是汉堡菜单。我已将其放置在工具栏的首位。

另一个辅助组件是工具栏标题。我把它添加到工具栏侧边栏图标之后。我显示的是数据中定义的 appTitle。

接下来,我有一系列按钮。Vuetify 按钮使用组件。对于前三个按钮,我指定了flat<v-btn>属性。扁平按钮没有盒子阴影,也没有背景。只有在鼠标悬停时才会显示按钮的容器。这允许我创建模仿传统菜单外观的按钮。

对于JOIN按钮,我没有使用 flat 属性。我给按钮添加了颜色。

我最后做的是添加了dark<v-toolbar>属性。这个属性将暗色主题变体应用于工具栏。这会将所有文本反转,使其不再是黑色,而是白色。

改善导航样式

导航的第一个实现提供了我想要的所有功能。但我想做一些修改。首先,我不希望汉堡菜单在小型设备上显示。同样,我也不希望在小型设备上显示菜单中的任何按钮。

Vuetify 提供了一个显示助手。显示助手允许您控制内容的显示。这包括根据当前视口或实际元素显示类型有条件地显示。

对于工具栏侧边图标,我希望它仅在 XS 和 SM 设备上可见。对于 MD 和 LG 屏幕,我希望工具栏侧边图标不可见。同样,我希望所有按钮在 MD 和 LG 屏幕上显示,在较小的屏幕上隐藏。

我将在工具栏侧边图标上添加类hidden-md-and-up 。我将在所有按钮和间隔符上添加类hidden-sm-and-down 。

现在我要在这里稍微谨慎一点,因为我想再添加一个布局更改。在小型设备上显示应用时,我只会看到汉堡菜单和应用标题。目前它们都在屏幕左侧。我想进行更改,让应用标题显示在屏幕右侧。这样可以在显示的两项内容之间取得平衡。

为此,我将<v-spacer>在工具栏侧边栏图标和工具栏标题之间​​添加一个新元素。这个分隔符会将其后的所有内容移至屏幕右侧。但我只希望这个分隔符在小屏幕上显示。因此,我为其添加了hidden-md-and-up类。

最终代码如下:



<v-toolbar app color="brown darken-4" dark>
    <v-toolbar-side-icon class="hidden-md-and-up" @click="drawer = !drawer"></v-toolbar-side-icon>
    <v-spacer class="hidden-md-and-up"></v-spacer>
    <v-toolbar-title>{{appTitle}}</v-toolbar-title>
    <v-btn flat class="hidden-sm-and-down">Menu</v-btn>
    <v-spacer class="hidden-sm-and-down"></v-spacer>
    <v-btn flat class="hidden-sm-and-down">SIGN IN</v-btn>
    <v-btn color="brown lighten-3" class="hidden-sm-and-down">JOIN</v-btn>
</v-toolbar>


Enter fullscreen mode Exit fullscreen mode

如果你想看看调整屏幕大小后的效果,这是我创建的第一个 giphy。🙂

调整屏幕大小

为小屏幕创建导航

对于小屏幕,我们将使用 Vuetify 的<v-navigation-drawer>组件。如果我们将其添加到模板中,会立即报错。这是因为每个 Vue 组件在模板中都只能有一个根。而在我们的模板中同时包含<v-navigation-drawer><v-toolbar>,就有两个根了。为了避免这种情况,请创建一个<span>来包裹这两个根。

以下是导航抽屉的代码:



<template>
    <span>
        <v-navigation-drawer app v-model="drawer" class="brown lighten-2" dark disable-resize-watcher>
            <v-list>
                <template v-for="(item, index) in items">
                    <v-list-tile :key="index">
                        <v-list-tile-content>
                            {{item.title}}
                        </v-list-tile-content>
                    </v-list-tile>
                    <v-divider :key="`divider-${index}`"></v-divider>
                </template>
            </v-list>
        </v-navigation-drawer>
        <v-toolbar app color="brown darken-4" dark>
            <v-toolbar-side-icon class="hidden-md-and-up" @click="drawer = !drawer"></v-toolbar-side-icon>
            <v-spacer class="hidden-md-and-up"></v-spacer>
            <v-toolbar-title>{{appTitle}}</v-toolbar-title>
            <v-btn flat class="hidden-sm-and-down">Menu</v-btn>
            <v-spacer class="hidden-sm-and-down"></v-spacer>
            <v-btn flat class="hidden-sm-and-down">SIGN IN</v-btn>
            <v-btn color="brown lighten-3" class="hidden-sm-and-down">JOIN</v-btn>
        </v-toolbar>
    </span>
</template>

<script>
export default {
    name: 'AppNavigation',
    data() {
        return {
            appTitle: 'Meal Prep',
            drawer: false,
            items: \[
                { title: 'Menu' },
                { title: 'Sign In' },
                { title: 'Join' }
            \]
        };
    }
};
</script>

<style scoped>
</style>


Enter fullscreen mode Exit fullscreen mode

让我解释一下我为抽屉导航添加了什么。我添加了app这个属性。这和我们为工具栏添加的属性相同。接下来,我添加了一个 v-model,它正在寻找名为 drawer 的数据项。在数据中, drawer 最初将设置为false。这意味着抽屉已关闭。当它为 true 时,抽屉将打开,为 false 时,抽屉将关闭。我在工具栏侧面图标上添加了一个 click 方法。当您单击汉堡菜单时,它会将 drawer 的值从 true 更改为 false 或反之亦然。

我添加的最后一项是给它添加一个颜色为棕色的类,颜色为 lighten-2。由于默认颜色是白色,所以我决定给抽屉添加一种颜色。

接下来我将使用 Vuetify 的<v-list>组件。在数据中,我创建了一个名为 items 的数组。这是一个对象数组。每个对象都有一个文本键,其值是菜单中显示的内容。我使用数据项而不是在列表中硬编码菜单项,因为我们将在后续系列文章中添加身份验证时使用它。

在数据中,我添加了抽屉和物品:



export default {
    name: 'AppNavigation',
    data() {
        return {
            appTitle: 'Meal Prep',
            drawer: false,
            items: \[
                { title: 'Menu' },
                { title: 'Sign In' },
                { title: 'Join' }
            \]
        };
    }
};


Enter fullscreen mode Exit fullscreen mode

当我们点击汉堡菜单时,抽屉将如下所示:

小型设备的抽屉导航

向应用程序添加导航

现在我们已经创建了 AppNavigation 组件,我们需要将它添加到我们的应用程序中。打开 App.vue 文件。在该文件内,我们需要导入 AppNavigation 组件。然后,我们就可以将它添加到应用程序中了。

以下是您的 App.vue 文件中应该包含的代码:



 <template>
    <v-app>
        <app-navigation></app-navigation>

        <v-content transition="slide-x-transition">
            <router-view></router-view>
        </v-content>
    </v-app>
</template>

<script>
import AppNavigation from '@/components/AppNavigation';

export default {
    name: 'App',
    components: {
        AppNavigation
    }
};
</script>

<style>
</style>


Enter fullscreen mode Exit fullscreen mode

首先,您需要导入 AppNavigation。导入时,我将其命名为 AppNavigation。在脚本中,我添加了一个包含 AppNavigation 的组件对象。名称的格式很重要。添加组件时,名称会使用连字符连接。将组件放入 html 模板时,我使用带连字符的名称。

注意:如果你仔细观察代码,你会发现我把 删除了,直接放在了 上<v-content>。我只是想让你知道我做了这个改变,因为我真的不想回去更新所有的图片!

为我们的主页创建内容

我们将为主页添加一张全屏图片。然后,我们将在图片上添加文字。我不会将代码直接放在 views 文件夹中的 Home.vue 文件中,而是创建一个新的 Vue 组件。在 components 文件夹中,创建一个名为 HomeHero.vue 的新文件。

Vuetify 拥有 12 点网格系统。该网格使用 flex-box 构建,用于布局应用程序的内容。v -container可用于居中页面,或使用fluid属性扩展其宽度。v-layout 用于分隔各个部分。布局结构如下:v-container » v-layout » v-flex

我们将在 HomeHero 组件的设计中使用这个网格系统。我们将把<v-container fluid>它用作模板中的根元素。我们将为其添加fill-height属性。此属性会自动调整容器的高度,使其达到屏幕的 100%。最后,我添加一个名为home-hero的类。

在我的样式中,我将为容器添加一张背景图片。这是用户在加载网站时看到的全屏图片。我使用的图片来自 unsplash.com。

在容器内我将添加一个<v-layout>。布局将包裹显示在图像顶部的所有文本。Vuetify 提供了排版设置,我将使用它来设置文本样式。对于正文,我将其设置为


 font-weight-black white--text"

Enter fullscreen mode Exit fullscreen mode

display-4 将输出字体大小为 112sp、字体粗细为 light 的文本。我将通过指定 font-weight-black 来覆盖该字体粗细。我希望文本为白色,因此我可以添加white–text 。最后,我添加的是指定文本居中显示。

我将对第二行文本使用相同的样式。唯一的不同之处在于,我添加了mb-3的对齐方式。Vuetify 提供了 5 级间距。mb 表示应用 3 的 margin-bottom 值。这将在标题文本和子标题文本之间提供一些间距。

我最后添加的是在屏幕底部的一个按钮。添加这个按钮是因为有时由于图片是全屏的,用户可能不想向下滚动查看更多内容。图片的作用是向用户提供视觉提示,让他们知道下方还有更多内容。

我使用的<v-btn>是 Vuetify 的组件,它和我们在导航中使用的组件相同。这次我将 fab 属性应用于按钮。浮动按钮是圆形的,通常包含一个图标。我将添加一个向下箭头的图标。该<v-icon>组件要求您输入要显示的图标的名称。以下是所有可在 Vuetify 中使用的 Material 图标的列表

对于按钮,我将添加一个类,将 margin-top 设置为 5,并将颜色设置为与菜单相同的棕色。对于图标,我将其颜色设置为白色。我还将图标设置为大尺寸。

以下是 HomeHero 文件的代码:



<template>
    <v-container fluid fill-height class="home-hero">
        <v-layout justify-center align-center column pa-5>
            <div class="display-4 font-weight-black white--text text-xs-center">HEALTHY MEALS</div>
            <div class="display-4 font-weight-black white--text text-xs-center mb-3">FOR YOUR TABLE</div>
            <div class="display-1 font-weight-bold white--text text-xs-center">Finally be a foodie at home with fresh, chef-prepared meals delivered daily to your door.</div>
            <v-btn fab class="mt-5 brown darken-4">
            <v-icon large color="white">expand\_more</v-icon>
            </v-btn>
        </v-layout>
    </v-container>
</template>

<script>
export default {
    name: 'HomeHero'
};
</script>

<style scoped>
.home-hero {
    background: url('https://source.unsplash.com/0BhSKStVtdM');
    background-size: cover;
    width: 100%;
    height: 100%;
}
</style>


Enter fullscreen mode Exit fullscreen mode

将 HomeHero 组件添加到应用程序

现在我们已经创建了组件,我们需要将其添加到应用程序中。打开 views 文件夹中的 Home.vue 文件。就像我们对 AppNavigation 所做的那样,您需要导入该组件并将其放置在模板中。Home.vue 文件应如下所示:



<template>
    <span>
        <home-hero></home-hero>
    </span>
</template>

<script>
import HomeHero from '@/components/HomeHero';

export default {
    name: 'home',
    components: {
        HomeHero
    }
};
</script>


Enter fullscreen mode Exit fullscreen mode

向主页添加更多内容

现在我们的主页已经非常漂亮了。但我们需要添加更多内容来向潜在客户解释我们的餐食准备服务提供哪些功能。所以现在就添加吧。

对于内容,我们将创建一个名为 HomeDetails.vue 的新组件。在 components 文件夹中,创建一个名为 HomeDetails.vue 的新文件。对于内容,我将使用 Lorem Ipsum 作为文本。

我将使用 Vuetify 布局方案,通过创建带有<v-container>组件的根元素。在根元素内部,我将使用组件。对于布局,我将添加column<v-layout>属性。由于布局基于 Flexbox,因此它将垂直对齐所有内容。每个文本项都将包含在一个组件中。<v-flex>

标题将使用 Vuetify 排版类display-2。我希望这段文字居中。为了使其居中,我向该类添加了text-xs-center。最后要添加的是my-5。这会在 y 轴上添加一个边距,这意味着它添加了一个 margin-top 和一个 margin-bottom 。

接下来我要创建另一个<v-flex>条目。这个条目将包含一个标题和一个副标题。我想在文本周围添加一些空白,因此我添加了一个mt-3类。这将为所有文本项添加 3 的 margin-top 值。

这是我的 HomeDetails.vue 文件:



<template>
    <v-container>
        <v-layout column>
            <v-flex  class="display-2 text-xs-center my-5">Big Title Goes Here</v-flex>
            <v-flex>
                <div class="headline mt-3">Lorem ipsum</div>
                <p class="subheading mt-3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras pulvinar risus quis mauris interdum, in euismod nibh pretium. Etiam pulvinar tincidunt dapibus. Quisque sollicitudin, mauris a consequat consectetur, turpis nisl sollicitudin enim, id consectetur neque neque nec metus. Pellentesque dolor nisi, vulputate quis lobortis ac, tincidunt et quam. Mauris pulvinar blandit nisi nec mattis. Aliquam accumsan ut sem eget efficitur. Vivamus in tortor gravida eros laoreet condimentum nec vel dui. Nullam quam massa, ultrices eget tincidunt a, pulvinar ac libero.</p>
            </v-flex>
            <v-flex>
                <div class="headline mt-3">Lorem ipsum</div>
                <p class="subheading mt-3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras pulvinar risus quis mauris interdum, in euismod nibh pretium. Etiam pulvinar tincidunt dapibus. Quisque sollicitudin, mauris a consequat consectetur, turpis nisl sollicitudin enim, id consectetur neque neque nec metus. Pellentesque dolor nisi, vulputate quis lobortis ac, tincidunt et quam. Mauris pulvinar blandit nisi nec mattis. Aliquam accumsan ut sem eget efficitur. Vivamus in tortor gravida eros laoreet condimentum nec vel dui. Nullam quam massa, ultrices eget tincidunt a, pulvinar ac libero.</p>

                <p class="subheading mt-3">Nullam nec massa eu est fringilla lobortis. Praesent in enim in justo blandit varius. Cras placerat arcu in sapien rhoncus aliquet. Sed interdum tortor et tincidunt condimentum. Etiam consequat mi leo, in suscipit odio scelerisque molestie. Nam et purus consequat, iaculis augue vel, sagittis ligula. Vestibulum aliquet vulputate erat. Phasellus id mauris mauris. Nunc a maximus dolor. Curabitur ut vestibulum arcu. Curabitur non lacus justo. Cras varius a magna in semper. Nulla eros ante, consectetur faucibus sapien eu, rhoncus imperdiet dui. Sed viverra iaculis nunc, id pulvinar massa egestas vitae.</p>

                <p class="subheading mt-3">Aenean erat metus, imperdiet eget nisl laoreet, venenatis ultricies ante. In interdum ante vel dictum ullamcorper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sit amet gravida diam. Aliquam in tempor metus. Fusce pellentesque pharetra sem, et luctus justo tempor dictum. Ut feugiat est sed tristique egestas. Nullam posuere a nunc in blandit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse laoreet ultrices eros, nec malesuada enim semper sit amet. Maecenas efficitur consectetur accumsan. Etiam in aliquam turpis, ut pharetra nulla. Vestibulum malesuada, nulla id elementum cursus, nibh dui rhoncus felis, suscipit mattis felis enim sed ex. Pellentesque scelerisque aliquam lorem, vel mattis nibh tincidunt ac. Suspendisse ac nibh sit amet lacus ullamcorper maximus.</p>
            </v-flex>
            <v-flex>
                <div class="headline mt-3">Lorem ipsum</div>
                <p class="subheading mt-3">Nullam nec massa eu est fringilla lobortis. Praesent in enim in justo blandit varius. Cras placerat arcu in sapien rhoncus aliquet. Sed interdum tortor et tincidunt condimentum. Etiam consequat mi leo, in suscipit odio scelerisque molestie. Nam et purus consequat, iaculis augue vel, sagittis ligula. Vestibulum aliquet vulputate erat. Phasellus id mauris mauris. Nunc a maximus dolor. Curabitur ut vestibulum arcu. Curabitur non lacus justo. Cras varius a magna in semper. Nulla eros ante, consectetur faucibus sapien eu, rhoncus imperdiet dui. Sed viverra iaculis nunc, id pulvinar massa egestas vitae.</p>
            </v-flex>
        </v-layout>
    </v-container>
</template>

<script>
export default {
    name: 'HomeDetails'
};
</script>

<style scoped>
</style>


Enter fullscreen mode Exit fullscreen mode

将 HomeDetails 添加到应用程序

我们将像 HomeHero 一样将 HomeDetails 添加到应用程序中。打开 views 文件夹中的 Home.vue 文件。您需要导入 HomeDetails 组件。然后将其添加到 HomeHero 下方的模板中。

Home.vue 文件如下所示:



<template>
    <span>
        <home-hero></home-hero>
        <home-details></home-details>
    </span>
</template>

<script>
import HomeHero from '@/components/HomeHero';
import HomeDetails from '@/components/HomeDetails';

export default {
    name: 'home',
    components: {
        HomeHero,
        HomeDetails
    }
};
</script>


Enter fullscreen mode Exit fullscreen mode

当我们添加这个新组件时,它会导致布局出现问题。现在,文本会根据图像的总高度以及新的文本内容居中。如下所示:

我们的布局有问题。

我们可以通过为包含图片的容器指定最大高度来轻松解决这个问题。我们希望这个容器的高度为视口高度的 100%。

打开 HomeHero.vue 文件。在<v-container>组件上添加一个设置最大高度的样式。如下:


 fluid fill-height class="home-hero" style="max-height: 100vh;">

Enter fullscreen mode Exit fullscreen mode

现在我们又回到了全屏图像,文本居中显示。然后我们可以向下滚动查看详细信息。

创建膳食计划组件

在详细信息之后,我想添加我们在餐食准备网站上提供的餐食计划的图片。我的餐食准备网站将提供生酮饮食、原始人饮食和纯素饮食计划。您可以自由定制您的应用程序,以提供您想要提供给客户的餐食计划。

让我们创建一个新组件。在 components 文件夹中,创建一个名为 HomePlans.vue 的新文件。我们将使用 Vuetify 网格布局。我们的根元素是 a <v-container>。我们将添加一个新的属性grid-list-lg。我们将并排显示三个膳食计划。此属性用于在它们之间添加间距。

接下来,我们将使用一个<v-layout>标题文本来宣布我们可用的膳食计划。我们将使用一个名为 的新 Vuetify 组件<v-card>。我们的卡片将包含一张图片、膳食计划名称和一些详细信息。我将使用来自 Unsplash 的图片来展示每个膳食计划。

以下是 HousePlans.vue 文件的代码:



<template>
    <v-container grid-list-lg>
        <v-layout row>
            <v-flex xs12 class="text-xs-center display-1 font-weight-black my-5">Available Meal Plans</v-flex>
        </v-layout>
        <v-layout row wrap>
            <v-flex xs12 sm12 md4>
                <v-card>
                    <v-img src="https://source.unsplash.com/hjCA3ecCXAQ" height="500px">
                        <v-container fill-height fluid>
                            <v-layout fill-height>
                                <v-flex xs12 align-end flexbox>
                                    <span class="headline white--text">KETO</span>
                                </v-flex>
                            </v-layout>
                        </v-container>
                    </v-img>

                    <v-card-title primary-title>
                        <div>
                            <h3 class="headline mb-0">Keto</h3>
                            <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mauris felis, varius rutrum massa a, dignissim ornare dui. Cras eget velit eu dui tristique lobortis sit amet vel tellus.
                            </div>
                        </div>
                    </v-card-title>
                </v-card>
            </v-flex>

            <v-flex xs12 sm12 md4>
                <v-card>
                    <v-img src="https://source.unsplash.com/6S27S6pZ6o0" height="500px">
                        <v-container fill-height fluid>
                            <v-layout fill-height>
                                <v-flex xs12 align-end flexbox>
                                    <span class="headline white--text">PALEO</span>
                                </v-flex>
                            </v-layout>
                        </v-container>
                    </v-img>
                    <v-card-title primary-title>
                        <div>
                            <h3 class="headline mb-0">Paleo</h3>
                            <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mauris felis, varius rutrum massa a, dignissim ornare dui. Cras eget velit eu dui tristique lobortis sit amet vel tellus.
                            </div>
                        </div>
                    </v-card-title>
                </v-card>
            </v-flex>

            <v-flex xs12 sm12 md4>
                <v-card>
                    <v-img src="https://source.unsplash.com/1SPu0KT-Ejg" height="500px">
                        <v-container fill-height fluid>
                            <v-layout fill-height>
                                <v-flex xs12 align-end flexbox>
                                    <span class="headline white--text">VEGAN</span>
                                </v-flex>
                            </v-layout>
                        </v-container>
                    </v-img>
                    <v-card-title primary-title>
                        <div>
                            <h3 class="headline mb-0">Vegan</h3>
                            <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mauris felis, varius rutrum massa a, dignissim ornare dui. Cras eget velit eu dui tristique lobortis sit amet vel tellus.
                            </div>
                        </div>
                    </v-card-title>
                </v-card>
            </v-flex>
        </v-layout>
    </v-container>
</template>

<script>
export default {
    name: 'HomePlans'
};
</script>

<style scoped>
</style>


Enter fullscreen mode Exit fullscreen mode

将 HomePlans 添加到应用程序

我们之前已经做过几次了。打开 views 文件夹中的 Home.vue 文件。导入 HomePlans.vue 组件并将其放置在 HomeDetails 下方的模板中。

这是 Home.vue 的代码:



<template>
    <span>
        <home-hero></home-hero>
        <home-details></home-details>
        <home-plans></home-plans>
    </span>
</template>

<script>
import HomeHero from '@/components/HomeHero';
import HomeDetails from '@/components/HomeDetails';
import HomePlans from '@/components/HomePlans';

export default {
    name: 'home',
    components: {
        HomeHero,
        HomeDetails,
        HomePlans
    }
};
</script>


Enter fullscreen mode Exit fullscreen mode

膳食计划部分如下所示:

可用的膳食计划。

获取代码

虽然本系列文章分为 4 部分,但您可以在我的 GitHub 账户中获取完整的代码。获取代码后,请帮助我并给代码库加星标。

概括

在本系列的第一部分中,您已经了解了:

  • 如何安装 Vue
  • 如何将 Vuetify 添加到应用程序
  • 如何创建多个组件
  • 如何使用 Vuetify 来设置组件样式

下一步

在本系列的下一篇中,我们将介绍 Vue Router。Vue Router 允许您在应用程序中的不同页面之间导航。例如,我们显示可用菜单的列表。当用户点击其中一个菜单时,应该显示该菜单的详细信息。我们将使用 Vue Router 从食谱列表页面过渡到详细信息页面。下一课再见。

培训课程

我在我的网站 CodePrep 上创建培训课程。我提供 Vue、Webpack、Flexbox、函数式编程等主题的培训课程。点击此处查看。

文章来源:https://dev.to/ratracegrad/how-to-build-a-single-page-application-using-vue-js-vuex-vuetify-and-firebase-part-1-of-4-3a63
PREV
初学者算法 学习算法的算法
NEXT
Web 开发的未来:每个开发人员都应该知道的新兴趋势和技术