在 Vue 中创建 Pinterest 风格的图片库

2025-06-10

在 Vue 中创建 Pinterest 风格的图片库

在本文中,我将展示一种快速简便的方法,创建一个 Pinterest 风格的布局网格来展示图片。该网格具有响应式设计,这意味着它会随着浏览器窗口的增大或减小而自动调整大小。这样一来,无论图片的高度如何,它都会自动显示,并且不会将所有图片拉平,使它们从同一行开始。相反,当某一列的图片显示完毕后,下一张图片就会开始显示,这样一来,图片板的布局中所有图片的对齐方式就不一致了。那就让我们开始吧。

我们将要创造什么

这是我们将要创建的流畅的 Pinterest 风格布局。

从 Unsplash 获取图像

Pinterest 是一个允许用户展示特定主题(例如婚礼、度假或其他任何主题)图片的平台。为了使这个应用正常运行,我需要一种方法来获取与特定主题对应的一系列图片。Unsplash 是一个很棒的图片网站。

Unsplash 的网站有一个搜索框,您可以在其中输入要搜索的主题,它会返回与该主题对应的所有图片。我们将复制此设置,允许用户点击与单个主题的搜索对应的按钮。当用户点击按钮时,它会使用我们 Pinterest 风格的网格显示来自 Unsplash 的图片。

创建开发者帐户

要使用 Unsplash API,您需要创建一个开发者帐户。前往 Unsplash

点击“注册为开发者”按钮。填写必填字段以创建您的帐户。创建帐户后,您需要验证您的电子邮件。只需点击他们发送给您的电子邮件即可验证您的帐户。

登录您的账户。您需要创建一个新的申请。点击“新建申请”按钮。

您将看到四个选项,必须点击确认每个选项。全部勾选后,点击“接受条款”按钮。申请时,您将获得一个唯一的访问密钥。



我们将在调用 Unsplash API 检索图像时使用此访问密钥。

创建我们的应用程序

现在我们准备在 Vue.js 中创建 Pinterest 克隆版本。我们将使用 Vue CLI 来创建应用程序。如果您尚未安装 Vue CLI,可以使用以下命令进行全局安装:

npm install -g @vue/cli

现在我们可以使用 Vue CLI 创建应用程序了。我将我的应用程序命名为 vue-pinterest。要创建应用程序,请在终端中输入以下命令:

vue create vue-pinterest

CLI 将询问您是否要使用默认设置或手动选择功能。

在本演示中,我使用默认设置,因此您只需按 Enter 键即可。

此命令运行完成后,它将显示有关如何访问新创建的应用程序的说明。

因此,让我们按照这些说明,使用以下命令切换到 vue-printerest 目录:

cd vue-pinterest

要启动我们的服务器,请运行以下命令:

npm run serve

我们可以通过打开浏览器并访问以下 URL 来测试我们的服务器是否正在运行:

localhost:8080

将包添加到我们的应用程序

如果您的服务器仍在运行,则需要将其停止。我们将使用两个软件包来为我们的 Pinterest 风格网格应用程序提供功能。我们要使用的第一个软件包是axios。Axios 将提供用于调用 Unsplash API 来检索图片的 http 客户端。第二个软件包是vue-stack-grid。这个软件包是一个 Vue 组件,它将为我们创建 Pinterest 风格的布局。要安装它们,请运行以下命令:

npm install axios vue-stack-grid

构建我们的应用程序

由于我们使用 Vue CLI 创建了应用程序,它为我们创建了一个初始布局。我们将删除所有这些,然后开始设计。打开 src 目录中的 App.vue 文件。在模板部分,删除除初始 div 之外的所有内容。您的模板应该如下所示:

<template>
  <div id="app">
  </div>
</template>

首先,我们将创建一个容器来显示所有图片。容器内会有一个包装器,用于放置所有按钮。每个按钮将显示与特定主题相关的图片,例如秋天或海洋主题的图片。我们先创建一个按钮,之后再添加其他按钮。为此,请将以下内容添加到您的 App.vue 文件:

<template>
  <div id="app">
    <div class="container">
      <div class="button-wrapper">
        <button class="btn" @click="searchUnsplash('Autumn')">Autumn</button>
      </div>
    </div>
  </div>
</template>

现在我们已经添加了这些,让我们为我们的containerbutton-wrapperbtn类添加一些样式。这些样式将添加到底部的样式部分。

对于容器,我们将其宽度设置为屏幕宽度的 80%,并将其置于屏幕中央。这将为我们的网站访问者提供熟悉的观感:内容位于屏幕中央,且内容两侧留有等量的空白。

对于button-wrapper类,我想使用 flexbox 布局让按钮在屏幕上居中。我还想在按钮下方留出边距,这样按钮和图片开始显示的位置之间就会有一些空白。

我要添加的最后一个样式是针对btn类的。我想给按钮一个绿色背景和白色文本。我希望按钮有 padding 和指定的字体大小。

以下是您需要为这三个类添加的样式:

.container {
  width: 80vw;
  margin: 0 auto;
}
.button-wrapper {
  display: flex;
  justify-content: center;
  margin-bottom: 25px;
}
.btn {
  font-size: 18px;
  background-color: #42b983;
  color: white;
  padding: 10px 20px;
}

显示来自 Unsplash 的图片

接下来我们需要调用 Unsplash API 来获取图片。在按钮中,我添加了一个名为searchUnsplash 的@click 函数。接下来我们来编写这个函数。该函数将使用我们之前安装的 axios 模块。要使用该模块,我们需要导入它。在脚本部分的第一行添加以下代码以导入 axios:

import axios from "axios";

接下来,让我们创建searchUnsplash函数。在脚本中添加一个方法部分并创建该函数。该函数将接受一个参数,即我们想要在 Unsplash 上搜索的主题。在这个函数中,我们想要调用 Unsplash API 并返回一个图片列表。要使用 axios 进行此调用,我们需要提供在 Unsplash 上创建应用程序时分配的应用程序访问密钥。我们将返回的图片存储在一个名为 images 的变量中。以下是 searchUnsplash 函数的代码,只需确保在标注的位置插入您的访问密钥即可:

searchUnsplash(topic) {
      this.images = [];
      axios
        .get(
          `https://api.unsplash.com/search/photos?query=${topic}&per_page=20`,
          {
            headers: {
              Authorization:
                "Client-ID <YourAccessKeyGoesHere>",
              "Accept-Version": "v1"
            }
          }
        )
        .then(response => {
          this.images = response.data.results;
        })
        .catch(() => {
          this.images = [];
        });
    }

我们调用的 URL 是 Unsplash API 的 URL。我将查询作为我们要搜索的主题传递。我添加的唯一其他选项是将per_page设置为显示 20 张图片,而不是默认的 10 张图片。我想显示更多图片,以便拥有更大的图片库。

我们将 API 调用的结果存储在一个名为 images 的变量中。现在就来创建它。在脚本中添加一个数据部分,并添加图像。我们将默认值设置为空数组。您的数据部分应该如下所示:

data: () => ({
    images: []
  }),

添加我们的 Pinterest 网格

最后一步是显示searchUnsplash函数返回的图片。为此,我们需要从之前安装的vue-stack-grid包中导入Stack和 StackItem 。因此,在导入 axios 的代码行下方添加以下内容:

import { Stack, StackItem } from "vue-stack-grid";

导入后,我们需要将这两个组件添加到我们的应用中。添加一个包含这两个项目的 components 部分。您的 components 部分应该如下所示:

components: {
    Stack,
    StackItem
  },

接下来,我们需要在模板部分添加这两个组件。第一个组件stack将用于设置网格中每列的宽度以及每张图片之间的内边距。第二个组件stack-item将用于包装网格中显示的每一张图片。

堆栈组件有一些可用的 props。我们将要使用的 props 是

  • column-min-width – 这是每列图像的宽度
  • 间距宽度 – 这是网格中每列之间的距离
  • 装订线高度 – 这是每列中每张图片上下的距离
  • Monitor-images-loaded – 这个 prop 告诉组件我们正在显示图像

我们将向stack-item标签添加一种样式,以便在最初显示图像时以及调整屏幕大小时提供一些动画。

我们的模板现在看起来是这样的:

<template>
  <div id="app">
    <div class="container">
      <div class="button-wrapper">
        <button class="btn" @click="searchUnsplash('Autumn')">Autumn</button>
      </div>
      <stack
              :column-min-width="300"
              :gutter-width="15"
              :gutter-height="15"
              monitor-images-loaded
      >
        <stack-item
                v-for="(image, i) in images"
                :key="i"
                style="transition: transform 300ms"
        >
          <img :src="image.urls.small" :alt="image.alt_description" />
        </stack-item>
      </stack>
    </div>
  </div>
</template>

测试我们的应用程序

通过在终端中输入以下命令来启动服务器:

npm run serve

转到浏览器并打开此网址:

localhost:8080

您应该看到以下显示:

添加更多搜索按钮

为了改进我们的应用程序,我们再添加两个按钮,用户点击后即可搜索图片。我们将添加用于搜索“悬崖”“海洋”的按钮。如果您想搜索不同的关键词,也可以这样做。您可以复制包含按钮的那一行,并粘贴两次,这样我们就有了三个按钮。对于每个按钮,请确保将传递给searchUnsplash函数的关键词更新为您想要搜索的关键词。同时,请更改按钮的文本以反映该关键词。

现在我们有三个按钮,分别用于搜索不同的关键词。唯一的问题是这三个按钮互相重叠。我想在按钮之间添加一些空白。我们可以在样式部分添加以下代码来实现:

.btn:not(:last-child) {
  margin-right: 10px;
}

在添加样式的同时,我们再为要显示的图片添加最后一个样式。Pinterest 会为图片添加圆角,所以我们也想添加。我们还希望图片的宽度与所在列的宽度一致。图片的高度会根据图片的宽度进行调整。这样,当屏幕尺寸调整时,图片的大小也会随之调整。因此,添加最后一个样式:

img {
  width: 100%;
  height: auto;
  border-radius: 12px;
}

获取代码

您可以从我的 GitHub 仓库获取本文的代码副本。请为该仓库点赞!

您可以在此处查看该应用程序的现场演示

结论

我们快速轻松地创建了一个 Pinterest 克隆版,用于在网格中显示图片。感谢您的阅读。请查看我的其他文章。您也可以点击此处在 Twitter 上关注我

鏂囩珷鏉ユ簮锛�https://dev.to/ratracegrad/creating-a-pinterest-style-image-gallery-in-vue-6dc
PREV
我正在读的 10 本书(不是同时读)
NEXT
防止滚动条导致的布局偏移