Skip to content

بارگذاری داده در زمان ساخت

ویت‌پرس یک ویژگی به نام بارگذارهای داده ارائه می‌دهد که به شما این امکان را می‌دهد که داده‌های دلخواه را بارگیری کنید و آن‌ها را از صفحات یا اجزا وارد کنید. بارگذاری داده فقط در زمان ساخت اجرا می‌شود: داده‌های حاصل به صورت JSON در بسته JavaScript نهایی سریالیزه می‌شوند.

بارگذارهای داده می‌توانند برای بارگیری داده‌های از راه دور یا تولید فراداده‌ها بر اساس فایل‌های محلی استفاده شوند. به عنوان مثال، می‌توانید از بارگذارهای داده استفاده کنید تا تمام صفحات API محلی خود را تجزیه کنید و به طور خودکار یک فهرست از تمام ورودی‌های API تولید کنید.

استفاده ابتدایی

یک فایل بارگذار داده باید با .data.js یا .data.ts پایان یابد. فایل باید یک صادرات پیش‌فرض از یک شی با متد load() داشته باشد:

js
// example.data.js
export default {
  load() {
    return {
      hello: 'world'
    }
  }
}

ماژول بارگذار فقط در Node.js ارزیابی می‌شود، بنابراین شما می‌توانید API ‌های Node و وابستگی‌های npm را به عنوان نیازهای خود وارد کنید.

سپس می‌توانید داده را از این فایل در صفحات .md و اجزا .vue با استفاده از صادرات نام‌گذاری شده data وارد کنید:

vue
<script setup>
import { data } from './example.data.js'
</script>

<pre>{{ data }}</pre>

خروجی:

json
{
  "hello": "world"
}

شما متوجه خواهید شد که بارگذار داده خودش داده را صادر نمی‌کند. ویت‌پرس پشت صحنه متد load() را فراخوانی می‌کند و به طور ضمنی نتیجه را از طریق صادرات نام‌گذاری شده data ارائه می‌دهد.

این کار حتی اگر بارگذار async باشد انجام می‌شود:

js
export default {
  async load() {
    // دریافت داده از راه دور
    return (await fetch('...')).json()
  }
}

داده از فایل‌های محلی

وقتی نیاز به تولید داده بر اساس فایل‌های محلی دارید، باید از گزینه watch در بارگذار داده استفاده کنید تا تغییرات اعمال شده به این فایل‌ها بتواند به روزرسانی‌های سریع منجر شود.

گزینه watch همچنین در آنجا مفید است که می‌توانید از الگوهای glob برای تطابق با چندین فایل استفاده کنید. الگوها می‌توانند نسبت به فایل بارگذار خود نسبی باشند و تابع load() فایل‌های تطابق یافته را به عنوان مسیرهای مطلق دریافت می‌کند.

مثال زیر نشان می‌دهد که چگونه فایل‌های CSV را بارگذاری کرده و آن‌ها را با استفاده از csv-parse به JSON تبدیل می‌کند. این فایل تنها در زمان ساخت اجرا می‌شود، بنابراین شما نیازی به ارسال پارسر CSV به مشتری ندارید!

js
import fs from 'node:fs'
import { parse } from 'csv-parse/sync'

export default {
  watch: ['./data/*.csv'],
  load(watchedFiles) {
    // watchedFiles یک آرایه از مسیرهای مطلق فایل‌های تطابق یافته خواهد بود.
    // تولید یک آرایه از فراداده‌های پست وبلاگ که می‌تواند برای نمایش
    // یک لیست در طرح استفاده شود
    return watchedFiles.map((file) => {
      return parse(fs.readFileSync(file, 'utf-8'), {
        columns: true,
        skip_empty_lines: true
      })
    })
  }
}

createContentLoader

وقتی که در حال ساختن یک سایت متمرکز بر محتوا هستیم، اغلب نیاز به ایجاد یک "بایگانی" یا "فهرست" صفحه داریم: یک صفحه که ما همه ورودی‌های موجود در مجموعه محتوای خود را لیست می‌کنیم، به عنوان مثال پست‌های وبلاگ یا صفحات API. ما می‌توانیم این کار را مستقیماً با API بارگذار داده انجام دهیم، اما از آنجا که این یک حالت استفاده رایج است، ویت‌پرس همچنین یک کمک‌کننده به نام createContentLoader را فراهم می‌کند تا این فرآیند را ساده‌تر کند:

js
// posts.data.js
import { createContentLoader } from 'vitepress'

export default createContentLoader('posts/*.md', /* گزینه‌ها */)

کمک‌کننده یک الگوی glob را نسبت به دایرکتوری منبع مشخص می‌کند و یک شی { watch، load } را که می‌تواند به عنوان صادرات پیش‌فرض در یک فایل بارگذار داده استفاده شود، برمی‌گرداند. همچنین پیاده‌سازی حافظه پنهانی بر اساس برچسب‌های تغییر مدیریت

می‌کند تا عملکرد توسعه را بهبود بخشد.

لطفاً توجه داشته باشید که بارگذار فقط با فایل‌های Markdown کار می‌کند - فایل‌های غیر-Markdown تطابق یافته حذف می‌شوند.

داده بارگذاری شده یک آرایه با نوع ContentData[] خواهد بود:

ts
interface ContentData {
  // آدرس URL برای صفحه. به عنوان مثال /posts/hello.html (شامل پایه نمی‌شود)
  // تکرار دستی یا استفاده از `transform` سفارشی برای نرمال کردن مسیرها
  url: string
  // اطلاعات frontmatter صفحه
  frontmatter: Record<string, any>

  // موارد زیر فقط وقتی که گزینه‌های مربوط فعال باشند
  // ما در زیر آنها را بررسی می‌کنیم
  src: string | undefined
  html: string | undefined
  excerpt: string | undefined
}

به طور پیش‌فرض، تنها url و frontmatter ارائه می‌شوند. این به خاطر این است که داده بارگذاری شده به عنوان JSON در بسته مشتری نهایی درج می‌شود، بنابراین ما باید در مورد اندازه آن محتاط باشیم. در زیر مثالی از استفاده از داده برای ساخت یک صفحه فهرست کمینه وبلاگ آورده شده است:

vue
<script setup>
import { data as posts } from './posts.data.js'
</script>

<template>
  <h1>همه پست‌های وبلاگ</h1>
  <ul>
    <li v-for="post of posts">
      <a :href="post.url">{{ post.frontmatter.title }}</a>
      <span>توسط {{ post.frontmatter.author }}</span>
    </li>
  </ul>
</template>

گزینه‌ها

احتمالاً داده پیش‌فرض به تمام نیازها پاسخ نمی‌دهد - شما می‌توانید با استفاده از گزینه‌ها به تبدیل داده‌ها مشترک شوید:

js
// posts.data.js
import { createContentLoader } from 'vitepress'

export default createContentLoader('posts/*.md', {
  includeSrc: true, // آیا منبع اصلی مارک‌داون را اضافه کنیم؟
  render: true,     // آیا صفحه HTML را نیز شامل کنیم؟
  excerpt: true,    // آیا خلاصه را نیز شامل کنیم؟
  transform(rawData) {
    // نقشه‌برداری، مرتب‌سازی یا فیلتر کردن داده‌های اصلی به دلخواه.
    // نتیجه نهایی آنچه است که به مشتری ارسال خواهد شد.
    return rawData.sort((a, b) => {
      return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
    }).map((page) => {
      page.src     // منبع اصلی مارک‌داون
      page.html    // صفحه HTML کامل
      page.excerpt // خلاصه HTML (محتوای بالای اولین `---`)
      return {/* ... */}
    })
  }
})

بررسی کنید که چگونه در وبلاگ Vue.js استفاده شده است.

API createContentLoader همچنین می‌تواند در داخل هوک‌های ساخت استفاده شود:

js
// .vitepress/config.js
export default {
  async buildEnd() {
    const posts = await createContentLoader('posts/*.md').load()
    // تولید فایل‌های بر اساس فراداده‌های پست‌ها، مثلاً فید RSS
  }
}

انواع

ts
interface ContentOptions<T = ContentData[]> {
  /**
   * آیا منبع اصلی را اضافه کنیم؟
   * @default false
   */
  includeSrc?: boolean

  /**
   * آیا منبع را به HTML تبدیل کرده و در داده شامل کنیم؟
   * @default false
   */
  render?: boolean

  /**
   * اگر `boolean` باشد، آیا باید خلاصه را تجزیه و شامل کنیم؟ (به صورت HTML)
   *
   * اگر `function` باشد، کنترل نحوه استخراج خلاصه از محتوا.
   *
   * اگر `string` باشد، تعیین کنید که چگونه جداکننده سفارشی باید برای استخراج خلاصه استفاده شود.
   * جداکننده پیش‌فرض `---` است اگر `excerpt` `true` باشد.
   *
   * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt
   * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt_separator
   *
   * @default false
   */
  excerpt?:
    | boolean
    | ((file: { data: { [key: string]: any }; content: string; excerpt?: string }, options?: any) => void)
    | string

  /**
   * تبدیل داده. توجه داشته باشید که داده به عنوان JSON در بسته مشتری درج خواهد شد
   * اگر از اجزا یا فایل‌های مارک‌داون وارد شود.
   */
  transform?: (data: ContentData[]) => T | Promise<T>
}

بارگذارهای داده تایپ شده

زمان استفاده از TypeScript، می‌توانید بارگذار و صادرات data خود را به این شکل تایپ کنید:

ts
import { defineLoader } from 'vitepress'

export interface Data {
  // نوع داده
}

declare const data: Data
export { data }

export default defineLoader({
  // گزینه‌های بارگذاری با تایپ چک شده
  watch: ['...'],
  async load(): Promise<Data> {
    // ...
  }
})

پیکربندی

برای دریافت اطلاعات پیکربندی در داخل یک بارگذار، می‌توانید از کدی مانند زیر استفاده کنید:

ts
import type { SiteConfig } from 'vitepress'

const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG

انتشار یافته تحت لایسنس MIT