AI 驅動的混合搜尋功能正在封閉測試中。 加入候補名單,搶先體驗!

前往首頁Meilisearch 的標誌
返回文章
2023 年 3 月 27 日

逐步指南:為您的 Nuxt 電商網站新增搜尋功能

想要為您的 Vue 電商網站新增網站搜尋功能嗎?在本完整的 Nuxt 指南中,學習如何整合即時排序、篩選和分面搜尋。

Laurent Cazanove
Laurent CazanoveDX 工程師兼文案@StriftCodes
A step by step guide to adding site search to your Nuxt ecommerce

搜尋是線上購物不可或缺的一部分。專注於客戶體驗的研究公司 Forrester 報告指出,使用網站內搜尋的訪客轉換率幾乎高出兩倍,並且花費更多時間購物。但糟糕的搜尋結果會降低銷售額和品牌信任度。電商網站搜尋需要快速、相關,並根據您業務的特定需求量身打造。

在本指南中,我們將引導您使用 JavaScript 框架 Nuxt 3 為電商網站建構搜尋體驗。

本指南分為三個部分

  • 設定全文搜尋資料庫
  • 建構「邊輸入邊搜尋」的體驗
  • 使用篩選器和分面來精煉搜尋結果

本指南中的程式碼也可以在 GitHub 儲存庫中找到,其中包含不同的檢查點以幫助您跟進。在本指南結束時,我們的應用程式將如下所示

Ecommerce website with real time search

最終應用程式的預覽 (線上檢視)

內容

  • 需求
  • 設定 Meilisearch 全文搜尋資料庫
  • 建構「邊輸入邊搜尋」的體驗
  • 使用排序、分面和分頁的高階搜尋模式

需求

為了建構連接到 Meilisearch 資料庫的 Nuxt Web 應用程式,我們將使用

  • Node 18 或更新版本 — 我們建議使用 nvm 來輕鬆切換版本
  • yarn 3 — Node.js 的套件管理員
  • Nuxt 3 — 一個使用 Vue 3 和 TypeScript 建構生產應用程式的框架
  • Meilisearch 1.3 — 一個搜尋引擎,可建立開箱即用的相關搜尋體驗

為了專注於與搜尋相關的事項,我們將使用範本儲存庫。此儲存庫包含用於建構傳統電商版面的 UI 元件。讓我們先從複製它開始

git clone https://github.com/meilisearch/ecommerce-demo

然後,讓我們安裝相依性

# Navigate to the project directory
cd ecommerce-demo

# Make sure to use Node.js 18.x before installing dependencies!
# nvm use v18

# Install dependencies
yarn

當安裝完成時,我們就可以開始設定資料庫了。

遇到任何問題嗎?請使用 Discord 上的說明頻道!

設定 Meilisearch 全文搜尋資料庫

在建構前端應用程式之前,我們將初始化 Meilisearch 資料庫。在第一部分中,我們將

  • 啟動 Meilisearch 資料庫
  • 將我們的資料集匯入產品索引
  • 設定我們的 Meilisearch 執行個體以進行電商搜尋

如果您正在使用本教學課程的儲存庫,請切換到 1-setup-database 分支

git checkout 1-setup-database

啟動 Meilisearch 資料庫

產生 Meilisearch 執行個體最簡單的方法是使用 Meilisearch Cloud。有 14 天的免費試用期,無需信用卡。Meilisearch 是開源的,因此如果您喜歡在本機上執行,可以參考 本機安裝上的文件。在本指南中,我們將使用 Meilisearch Cloud。

接下來,我們需要建立 Meilisearch Cloud 帳戶。登入後,我們會進入「專案」頁面。從那裡建立一個專案來產生新的資料庫(給它一個很酷的名稱,例如 awesome-ecommerce-tutorial 😏),選擇引擎版本,然後按一下「建立」–資料庫應該會在幾分鐘內準備好。在 Meili 小精靈為我們接上纜線的同時,讓我們繼續前進!

當專案準備就緒時,我們可以存取「專案總覽」頁面以擷取稍後章節中有用的資訊

  • 資料庫網址
  • 預設搜尋 API 金鑰
  • 預設管理員 API 金鑰

「搜尋 API 金鑰」提供唯讀權限:我們將在前端應用程式中使用它進行搜尋。「管理員 API 金鑰」允許更新資料庫及其設定–請務必將其保密!

匯入我們的產品資料集

我們的儲存庫在 database/data.json 中包含電商產品的範例資料集。我們將透過在 database/setup.js 檔案中建立 Meilisearch 用戶端將其匯入資料庫。

我們還需要為應用程式提供必要的憑證。為此,我們使用位於專案根目錄的 .env 檔案。.env 檔案是儲存憑證變數的常見方式,並且會由我們新增到 database/setup.js 的程式碼讀取。

首先,複製現有的 .env.example 檔案,並將其重新命名為 .env。然後,更新變數以符合您「專案總覽」頁面上找到的憑證。更新 Meilisearch 相關變數,使您的 .env 檔案看起來像這樣

# .env

# Meilisearch configuration
MEILISEARCH_HOST="use the Database URL here"
MEILISEARCH_ADMIN_API_KEY="use the Default Admin API Key here"
MEILISEARCH_SEARCH_API_KEY="use the Default Search API Key here"

# …

現在我們的環境持有資料庫憑證,我們可以建立 Meilisearch 用戶端來將內容新增到資料庫,這個過程稱為種子設定。使用 Meilisearch 時,針對資料庫執行的動作是異步的–我們稱它們為任務。我們將使用 watchTasks 輔助函式來等待任務完成,然後再結束我們的腳本。

database/setup.js 中的以下程式碼會將儲存在 database/data.json 中的資料傳送到 Meilisearch

// database/setup.js

import * as dotenv from 'dotenv'
import { MeiliSearch } from 'meilisearch'
import { watchTasks } from './utils.js'
import data from './data.json' assert { type: 'json' }

// Load environment
dotenv.config()

const credentials = {
  host: process.env.MEILISEARCH_HOST,
  apiKey: process.env.MEILISEARCH_ADMIN_API_KEY
}

const INDEX_NAME = 'products'

const setup = async () => {
  console.log('🚀 Seeding your Meilisearch instance')

  if (!credentials.host) {
    console.error('Missing `MEILISEARCH_HOST` environment variable')
    process.exit(1)
  }
  if (!credentials.apiKey) {
    console.error('Missing `MEILISEARCH_ADMIN_API_KEY` environment variable')
    process.exit(1)
  }

  const client = new MeiliSearch(credentials)

  console.log(`Adding documents to \`${INDEX_NAME}\``)
  await client.index(INDEX_NAME).addDocuments(data)

  await watchTasks(client, INDEX_NAME)
}

setup()

使用 Yarn 來執行我們的設定腳本

yarn setup

您應該會看到類似以下的輸出

🚀 Seeding your Meilisearch instance
Adding documents to `products`
Start update watch for products
-------------
products index: adding documents
-------------
All documents added to "products"
  Done in 2.92s.

如果它能運作,恭喜您–我們已連線到 Meilisearch 並匯入資料。 🎉

您可以透過在瀏覽器中導覽至您的資料庫網址來瀏覽 Meilisearch 執行個體的內容。

Meilisearch mini-dashboard

迷你儀表板可讓您瀏覽資料庫內容。

為電商設定 Meilisearch

Meilisearch 提供出色的搜尋預設值,包括對拼寫錯誤的容忍度,以及用於最佳化相關性的預定義排名規則。電商搜尋的其他主要功能包括排序和篩選。此外,根據行銷活動、合作夥伴關係或 <插入業務原因>,您可能想要實作自訂排名規則。

您可以透過調整資料庫設定來自訂 Meilisearch。我們將在 database/setup.js 檔案中執行此操作。

首先,讓我們決定一個組態

  • 篩選:我們希望產品可以依品牌、類別、標籤、評分、評論數和價格進行篩選;
  • 排序:我們希望產品可以依價格或評分進行排序;
  • 排名:我們希望演算法優先排序(在真正的商店中,您可能希望優先顯示特色產品)。

我們可以在 database/setup.js 檔案中實作此操作。我們將更新 setup() 函式主體,使其看起來像這樣

// database/setup.js

// …

const setup = async () => {
  // Credentials verification code…

  const client = new MeiliSearch(credentials);

  console.log(`Adding filterable attributes to \`${INDEX_NAME}\``);
  await client
    .index(INDEX_NAME)
    .updateFilterableAttributes([
      "brand",
      "category",
      "tag",
      "rating",
      "reviews_count",
      "price",
    ]);

  console.log(`Adding ranking rules to \`${INDEX_NAME}\``);
  await client
    .index(INDEX_NAME)
    .updateRankingRules([
      "sort",
      "words",
      "typo",
      "proximity",
      "attribute",
      "exactness",
    ]);

  console.log(`Adding sortable attributes to \`${INDEX_NAME}\``);
  await client.index(INDEX_NAME).updateSortableAttributes(["rating", "price"]);

  // Adding documents and watching tasks…
};

setup();

更新索引設定會觸發文件重新建立索引(即,完整的資料庫重建),這可能會影響單執行緒環境中的搜尋效能。為了避免這種情況,最好先設定設定,然後匯入資料。

在上面的程式碼中,我們更新了

  • 可篩選屬性 — 這可以啟用篩選和分面搜尋
  • 排名規則 — 我們保留 Meilisearch 預設值,但將排序移到最前面;
  • 可排序屬性 — 啟用結果排序。

雖然超出本指南的範圍,但務必也正確設定您的可搜尋屬性。這可以大幅提升索引效能

至此,我們已完成 Meilisearch 資料庫設定。✅ 那麼,讓我們開始建構我們的 Nuxt 3 電商網站吧,好嗎?

建構「邊輸入邊搜尋」的體驗

如果您正在使用 git 儲存庫,請切換到 2-search-as-you-type 分支

git checkout "2-search-as-you-type"

在繼續之前,請確保 MEILISEARCH_SEARCH_API_KEY 已在我們的 .env 檔案中定義。

建立 Meilisearch 用戶端

我們有一個正在執行的 Meilisearch 資料庫,但我們仍然需要一個用戶端應用程式來與其互動。如果我們看一下 package.json,我們會看到有兩個程式庫可供使用

  • vue-instantsearch (Vue InstantSearch) 用於建構與搜尋用戶端互動的 UI 元件;
  • @meilisearch/instant-meilisearch (Instant Meilisearch) 用於建立與 InstantSearch 相容的 Meilisearch 用戶端。

我們需要一個元件來處理資料庫的身份驗證,並讓應用程式的其他部分可以使用與搜尋相關的狀態。我們在 MeiliSearchProvider.vue 元件中執行此操作。它會接收索引名稱作為 prop,並包含一個插槽來包裝子元件,這些子元件將可以存取狀態。

<!-- components/organisms/MeiliSearchProvider.vue -->

<script lang="ts" setup>
  import { instantMeiliSearch } from "@meilisearch/instant-meilisearch";
  import { AisInstantSearch } from "vue-instantsearch/vue3/es";

  const props = defineProps<{
    indexName: string;
  }>();

  const { indexName } = toRefs(props);

  const { host, searchApiKey, options } = useRuntimeConfig().meilisearch;

  const searchClient = instantMeiliSearch(host, searchApiKey, options);
</script>

<template>
  <AisInstantSearch :index-name="indexName" :search-client="searchClient">
    <slot name="default" />
  </AisInstantSearch>
</template>

我們的元件本質上是 AisInstantSearch 元件的包裝器。AisInstantSearch 是基於 InstantSearch 的整合基礎:它處理身份驗證並使狀態可供其他 InstantSearch 元件使用。我們的程式碼執行三件事

  • 從執行階段組態中提取憑證和選項
  • 建立 InstantMeilisearch 用戶端(即與 InstantSearch 相容的 Meilisearch 用戶端)
  • 實例化 Vue InstantSearch 元件

我們將在首頁的根目錄,也就是 HomeTemplate.vue 中使用此元件。但是單獨使用,此元件無法執行太多操作。因此,在我們將所有內容連結起來之前,先實作我們的搜尋欄和結果。

使用搜尋欄發送查詢。我們的應用程式需要一個搜尋欄,讓使用者可以輸入查詢。

我們將更新 MeiliSearchBar.vue 元件來處理此問題。在此元件中,我們會將輸入欄位的內容作為查詢發送到我們的 Meilisearch 資料庫。由於現有的 SearchInput 元件,我們的程式碼可以非常簡單

<!-- components/organisms/MeiliSearchBar.vue -->

<script lang="ts" setup>
  import { AisSearchBox } from "vue-instantsearch/vue3/es";
</script>

<template>
  <AisSearchBox>
    <template #default="{ currentRefinement, refine }">
      <SearchInput
        :value="currentRefinement"
        @input="refine($event.currentTarget.value)"
      />
    </template>
  </AisSearchBox>
</template>

我們的元件使用來自 AisSearchBox 的插槽 props。插槽 props 允許父元件存取在子範圍內管理的狀態。在這裡,這些插槽 props 讓我們可以存取與搜尋相關的狀態,從而使我們能夠建構自訂 UI。有了這個,我們就能夠將請求發送到我們的 Meilisearch 資料庫。這意味著現在只缺少一件事 - 顯示搜尋結果。

顯示搜尋結果

最後,讓我們更新我們的 `MeiliSearchResults.vue` 元件,以顯示搜尋結果。我們將以標準的網格佈局顯示結果。我們可以利用 ProductCard 元件

<!-- components/organisms/MeiliSearchResults.vue -->

<script lang="ts" setup>
  import { AisHits } from "vue-instantsearch/vue3/es";
</script>

<template>
  <AisHits>
    <template #default="{ items }">
      <div class="items">
        <ProductCard
          v-for="product in items"
          :key="product.id"
          :name="product.title"
          :brand="product.brand"
          :price="product.price"
          :image-url="product.images[0]"
          :rating="product.rating"
          :reviews-count="product.reviews_count"
        />
      </div>
    </template>
  </AisHits>
</template>

<style src="~/assets/css/components/results-grid.css" scoped />

將它們連結起來

我們建立了三個元件:一個搜尋用戶端提供者、一個搜尋欄和一個搜尋結果網格。這些元件在 HomeTemplate.vue 中使用。使用這些元件的程式碼行目前已註解。在我們逐步完成本指南時,我們將取消註解對應的程式碼行,以查看我們的元件實際運作的情況。

讓我們取消註解使用 <MeiliSearchProvider/><MeiliSearchBar/><MeiliSearchResults/> 的程式碼行,以檢查我們的實作是否成功。我們的程式碼應該如下所示

<!-- components/templates/HomeTemplate.vue -->

<script lang="ts" setup>
  const sortingOptions = [
    { value: "products", label: "Featured" },
    { value: "products:price:asc", label: "Price: Low to High" },
    { value: "products:price:desc", label: "Price: High to Low" },
    { value: "products:rating:desc", label: "Rating: High to Low" },
  ];
</script>

<template>
  <MeiliSearchProvider index-name="products">
    <TheNavbar class="mb-5 shadow-l">
      <template #search>
        <MeiliSearchBar />
      </template>
    </TheNavbar>
    <div class="container mb-5">
      <div class="filters">
        <!-- Removed for clarity -->
      </div>
      <div class="results">
        <div class="mb-5 results-meta">
          <!-- <MeiliSearchStats /> -->
          <!-- <MeiliSearchSorting /> -->
        </div>
        <MeiliSearchResults class="mb-5" />
        <!-- <MeiliSearchPagination /> -->
      </div>
    </div>
  </MeiliSearchProvider>
</template>

<style src="~/assets/css/components/home.css" scoped />

我們現在擁有一個與 Meilisearch 整合的基本 Nuxt 3 應用程式的骨架。要以開發模式啟動我們的應用程式,請執行以下命令

yarn dev

預設情況下,開發伺服器 URL 是 localhost:3000。我們可以在瀏覽器中開啟它,然後… 鏘 🎉 我們應該能夠在搜尋框中輸入並看到結果出現

Ecommerce app with search bar and results.

一個帶有搜尋欄和結果的基本電子商務。

好的。我們有一個可以即時搜尋產品的工作應用程式。讓我們新增一些閃亮的功能,使其更適合真實世界的電子商務。✨

使用排序、分面和分頁的高階搜尋模式

如果您正在按照 git 儲存庫操作,請檢出 3-advanced-search-patterns 分支

git checkout "3-advanced-search-patterns"

排序結果

排序對於瀏覽搜尋結果至關重要。例如,使用者可能希望查看按價格或評分排序的產品。我們將更新 MeiliSearchSorting.vue 元件,以允許使用者使用我們現有的 BaseSelect 元件來變更結果的排序。我們將使其讓排序選項作為 props 接收。

<!-- components/organisms/MeiliSearchSorting.vue -->

<script lang="ts" setup>
  import { AisSortBy } from "vue-instantsearch/vue3/es";

  const props = defineProps<{
    options: Array<{
      value: string;
      label: string;
    }>;
  }>();

  const { options } = toRefs(props);
</script>

<template>
  <AisSortBy :items="options">
    <template #default="{ items, refine }">
      <BaseSelect :options="items" @change="refine($event.target.value)" />
    </template>
  </AisSortBy>
</template>

如果我們回頭看看我們的 HomeTemplate.vue 檔案,我們可以看見定義了以下陣列以用於 options prop

const sortingOptions = [
  { value: "products", label: "Featured" },
  { value: "products:price:asc", label: "Price: Low to High" },
  { value: "products:price:desc", label: "Price: High to Low" },
  { value: "products:rating:desc", label: "Rating: High to Low" },
];

要查看我們的排序元件實際運作的情況,請取消註解使用 <MeiliSearchSorting/> 的程式碼行。請注意,排序只有在您事先設定可排序的屬性後才會運作。

使用 facets 和篩選器縮小結果範圍

排序結果很好。但是對於龐大的產品目錄,電子商務網站也需要篩選器來精煉搜尋結果。這就是 facets 的用途。讓我們先新增一個細化清單,以按產品類別或品牌進行篩選。然後,我們將新增元件以按價格範圍和評分進行篩選。

Facet 篩選器

讓我們更新我們的 MeiliSearchFacetFilter.vue 元件,以顯示給定屬性的所有可能值的核取清單。我們將使 attribute 成為一個 prop,以便該元件可重複使用。在我們的案例中,我們會將其用於 categorybrand。元件程式碼應該如下所示

<!-- components/organisms/MeiliSearchFacetFilter.vue -->

<script lang="ts" setup>
  import { AisRefinementList } from "vue-instantsearch/vue3/es";

  const props = defineProps<{
    attribute: string;
  }>();

  const { attribute } = toRefs(props);
</script>

<template>
  <AisRefinementList :attribute="attribute" operator="or">
    <template #default="{ items, refine }">
      <BaseTitle class="mb-3 text-valhalla-100"> {{ attribute }} </BaseTitle>
      <BaseCheckbox
        v-for="item in items"
        :key="item.value"
        :value="item.isRefined"
        :label="item.label"
        :name="item.value"
        :disabled="item.count === 0"
        @change="refine(item.value)"
      >
        <BaseText
          tag="span"
          size="m"
          :class="[ item.count ? 'text-valhalla-500' : 'text-ashes-900']"
        >
          {{ item.label }}
          <BaseText tag="span" size="s" class="text-ashes-900">
            ({{ item.count.toLocaleString() }})
          </BaseText>
        </BaseText>
      </BaseCheckbox>
    </template>
  </AisRefinementList>
</template>

在取消註解我們的 HomeTemplate.vue 中相關的程式碼行之後,我們的應用程式現在應該顯示類別和品牌的清單。類別清單應該如下所示

A multi-facets selection list for category

類別篩選器允許僅顯示符合給定類別的產品。

🆕 選用 – Facet 搜尋和排序 facet 值

Meilisearch v1.3 引入了兩個功能:搜尋 facet 值排序 facet 值

搜尋 facet 值

搜尋 facet 值

按名稱或計數排序 facet 值

排序 facet 值

請查看儲存庫 main 分支上的 MeiliSearchFacetFilter.vue 元件,以了解如何實作它。

價格篩選器

若要新增價格範圍篩選器,我們將更新我們的 MeiliSearchRangeFilter.vue 元件。我們將使用我們現有的 RangeSlider 元件來顯示一個滑桿,允許使用者設定最小值和最大值

<!-- components/organisms/MeiliSearchRangeFilter.vue -->

<script lang="ts" setup>
  import { AisRangeInput } from "vue-instantsearch/vue3/es";

  interface Range {
    min: number;
    max: number;
  }

  const props = defineProps<{
    attribute: string;
  }>();

  const { attribute } = toRefs(props);

  const toValue = (
    currentValue: Range,
    boundaries: Range
  ): [number, number] => {
    return [
      typeof currentValue.min === "number" ? currentValue.min : boundaries.min,
      typeof currentValue.max === "number" ? currentValue.max : boundaries.max,
    ];
  };
</script>

<template>
  <AisRangeInput :attribute="attribute">
    <template #default="{ currentRefinement, range, refine }">
      <BaseTitle class="mb-3 text-valhalla-100"> {{ attribute }} </BaseTitle>
      <div class="slider-labels text-valhalla-500 mb-2">
        <BaseText size="m">
          <span class="text-ashes-900">$ </span>{{ currentRefinement.min ??
          range.min }}
        </BaseText>
        <BaseText size="m">
          <span class="text-ashes-900">$ </span>{{ currentRefinement.max ??
          range.max }}
        </BaseText>
      </div>
      <RangeSlider
        :model-value="toValue(currentRefinement, range)"
        :min="range.min"
        :max="range.max"
        @update:model-value="refine($event)"
      />
    </template>
  </AisRangeInput>
</template>

<style scoped>
  .slider-labels {
    display: flex;
    justify-content: space-between;
  }
</style>

移除 HomeTemplate.vue 中對應程式碼行之前的註解,然後就完成了!

A range slider allowing to set minimum and maximum values

價格範圍篩選器允許設定最小價格和最大價格。

評分篩選器

對於線上購物者來說,一個有用的篩選方式是移除低於給定平均評分的產品,因此讓我們更新我們的 MeiliSearchRatingFilter.vue 元件來處理此問題。我們將使用來自 vue-instantsearchAisRatingMenu 元件,該元件有一個限制:它只能使用整數值作為評分。因此,我們將為其提供 rating_rounded 屬性而不是 rating。我們的元件將接受兩個 props:attributelabel(選用)。

<!-- components/organisms/MeiliSearchRatingFilter.vue -->

<script lang="ts" setup>
  import { AisRatingMenu } from "vue-instantsearch/vue3/es";

  const props = defineProps<{
    attribute: string;
    label?: string;
  }>();

  const { attribute, label } = toRefs(props);
</script>

<template>
  <AisRatingMenu :attribute="attribute" :max="5">
    <template #default="{ items, refine }">
      <BaseTitle class="mb-3 text-valhalla-100">
        {{ label ?? attribute }}
      </BaseTitle>
      <a
        v-for="item in items"
        :key="item.value"
        class="rating-link"
        :class="[item.isRefined ? 'text-dodger-500' : 'text-valhalla-500']"
        href="#"
        @click.prevent="refine(item.value)"
      >
        <span class="rating-label">
          <StarRating :rating="Number(item.value)" />
          <BaseText tag="span" size="m" class="ml-1">
            & Up
            <BaseText tag="span" size="s" class="text-ashes-900">
              ({{ item.count.toLocaleString() }})
            </BaseText>
          </BaseText>
        </span>
      </a>
    </template>
  </AisRatingMenu>
</template>

<style src="~/assets/css/components/rating-filter.css" scoped />

然後就完成了!

A list allowing users to filter out items by minimum rating

評分篩選器元件允許按最低評分進行篩選。

為結果分頁

我們將實作一個分頁系統,以允許使用者更輕鬆地找到結果。在電子商務情境中,[建議使用編號分頁](/blog/pagination-vs-infinite-scroll-vs-load-more/?utm_campaign=ecommerce-demo&utm_source=blog),因為它允許使用者記住頁面,因此如果他們想找到先前看過的產品,可以更輕鬆地返回這些頁面。讓我們更新我們的 MeiliSearchPagination.vue 元件

<script lang="ts" setup>
  import { AisPagination } from "vue-instantsearch/vue3/es";
</script>

<template>
  <AisPagination>
    <template
      #default="{ currentRefinement, pages, refine, nbPages, isFirstPage, isLastPage }"
    >
      <!-- First page -->
      <PageNumber
        v-if="!isFirstPage && !pages.includes(0)"
        :has-gap-separator="!pages.includes(1)"
        :is-current="currentRefinement === 0"
        @page-click="refine(0)"
      >
        Page 1
      </PageNumber>
      <!-- Current page and 3 previous/next -->
      <PageNumber
        v-for="(page, index) in pages"
        :key="page"
        :show-separator="index < (pages.length-1)"
        :is-current="currentRefinement === page"
        @page-click="refine(page)"
      >
        Page {{ page + 1 }}
      </PageNumber>
      <!-- Last page -->
      <PageNumber
        v-if="!isLastPage && !pages.includes(nbPages-1)"
        separator="before"
        :has-gap-separator="!pages.includes(nbPages-2)"
        :is-current="currentRefinement === nbPages-1"
        @page-click="refine(nbPages-1)"
      >
        Page {{ nbPages }}
      </PageNumber>
    </template>
  </AisPagination>
</template>

在取消註解我們的 HomeTemplate.vue 檔案中對應的程式碼行之後,我們現在將在結果下方看到一個頁面清單。此清單將始終顯示第一頁和最後一頁,以及當前頁面和前後最多 2 個頁面。

A list of pages

分頁元件會顯示一個頁面清單。

這樣,我們就完成了我們的電子商務應用程式。恭喜您完成本指南。🎉

我們的最終應用程式應該如下所示

An ecommerce application with real time site search with filters, facets, and pagination

我們的最終應用程式(查看即時版本

總結

讓我們回顧一下我們建立的內容

  • 一個 Nuxt 3 電子商務網站
  • 一個 Node.js 指令碼,用於初始化我們的 Meilisearch 資料庫以進行電子商務搜尋
  • 用於搜尋產品以及顯示、篩選和排序結果的 InstantSearch 整合

所有程式碼都可以在示範儲存庫中找到:https://github.com/meilisearch/ecommerce-demo

儲存庫的 main 分支包含一些小差異,例如 Meilisearch 作為 Nuxt 模組實作。對於希望實作伺服器端渲染以改善 SEO 的使用者來說,此方法將很有用。為了簡潔起見,本指南中省略了諸如伺服器端渲染和與路由器同步狀態等進階主題。

感謝您的閱讀!我希望本指南對您有所幫助。請在我們的 Discord 社群 中告訴我!

以下是與我們聯絡的其他方式

How to add AI-powered search to a React app

如何在 React 應用程式中新增人工智慧驅動的搜尋

使用 Meilisearch 的人工智慧驅動搜尋來建立 React 電影搜尋和推薦應用程式。

Carolina Ferreira
Carolina Ferreira2024 年 9 月 24 日
Build your Next.js Shopify storefront with Blazity

使用 Blazity 建立您的 Next.js Shopify 店面

了解如何使用 Next.js 和 Blazity commerce starter 建立 Shopify 店面。

Laurent Cazanove
Laurent Cazanove2024 年 8 月 19 日
Meilisearch 1.8

Meilisearch 1.8

Meilisearch 1.8 帶來了負關鍵字搜尋、搜尋穩健性和人工智慧搜尋的改進,包括新的嵌入器。

Carolina Ferreira
Carolina Ferreira2024 年 5 月 7 日