Vue3 組件生成提示詞(script setup + TypeScript、Props 與 Emits 類型、組合式函數抽離、Pinia 狀態)

用 Vue3 開發業務組件(表格頁、表單彈窗、帶搜尋的選擇器)時用:描述組件功能和交互,得到符合 Vue3 組合式 API 寫法的組件代碼,類型完整、邏輯拆成可複用的組合式函數,並說明響應式使用上的常見陷阱。

NNathaniel bigo··原創首發·AI 輔助撰寫
通用大模型 對話模型通用
你是一名熟悉 Vue 3 組合式 API 和 TypeScript 的前端工程師。請幫我寫一個組件。

- 組件名稱與用途:[組件名稱與用途](例:UserSelect 可搜尋的用戶選擇器)
- 功能與交互:[功能與交互](例:輸入關鍵字遠程搜尋、支持多選、最多選 5 個)
- 輸入與輸出:[輸入與輸出](例:v-model 綁定選中用戶 ID 數組,選中變化時觸發 change)
- UI 組件庫:[UI 組件庫](例:Element Plus、Naive UI、無)
- 狀態管理:[狀態管理](例:需要從 Pinia 讀取當前用戶,沒有就寫無)
- 項目約定:[項目約定](例:樣式用 scoped SCSS、接口請求封裝在 api 目錄)

要求:
1. 使用 script setup 加 TypeScript。Props 用基於類型的聲明並給出預設值;事件用類型化的聲明;需要雙向綁定時使用當前版本推薦的 v-model 寫法(說明版本要求)。
2. 把與介面無關的邏輯(遠程搜尋、防抖、請求取消、加載與錯誤狀態)抽到一個組合式函數中,組件只負責組裝和展示。
3. 響應式:說明這裏用 ref 還是 reactive 以及原因;解構 Props 或 reactive 對象時如何保持響應性;計算屬性中不要產生副作用;watch 的觸發時機與清理(組件卸載或參數變化時取消舊請求)。
4. 邊界情況:搜尋結果為空、請求失敗、輸入很快時舊請求的結果晚到覆蓋新結果、達到選擇上限。
5. 可訪問性:鍵盤可操作、加載狀態有提示文字。
6. 給出一個父組件中使用它的示例,以及一份用 Vitest 和 Vue Test Utils 編寫的測試(至少覆蓋搜尋、選擇、達到上限三種情況)。

輸出:組合式函數文件、組件文件、使用示例、測試文件,代碼帶中文註釋。

高亮處換成你自己的內容:[組件名稱與用途]、[功能與交互]、[輸入與輸出]、[UI 組件庫]、[狀態管理]、[項目約定]

ChatGPT Plus 充值

已被複製 0 次

使用說明

怎麼填變量:[輸入與輸出] 寫清楚組件對外的「接口」:用 v-model 綁定什麼值、會觸發哪些事件。[項目約定] 貼上後,AI 會沿用你的接口封裝和樣式寫法,生成的代碼可以直接放進項目。

常見坑:

  • 直接解構 reactive 對象或 Props,得到的變量失去響應性,介面不會更新。需要時用 toRefs 或計算屬性。
  • 遠程搜尋沒有處理「舊請求後返回」的問題:用戶快速輸入「張」「張三」,如果「張」的結果後到,會覆蓋「張三」的結果。要取消舊請求或者忽略過期結果。
  • 所有邏輯都寫在組件裏,幾百行難以維護和測試。可複用的邏輯抽成組合式函數。

追問技巧:追問「把這個組件改成支持分頁加載更多」,或「這個組合式函數還能在哪些組件中複用,需要怎麼調整參數」。

示例輸出

示例,僅供參考(組合式函數節選)
ts
// composables/useRemoteSearch.ts
import { ref, watch, onScopeDispose, type Ref } from 'vue'

export function useRemoteSearch<T>(keyword: Ref<string>, fetcher: (q: string, signal: AbortSignal) => Promise<T[]>) {
  const results = ref<T[]>([]) as Ref<T[]>
  const loading = ref(false)
  const error = ref<string | null>(null)
  let controller: AbortController | null = null
  let timer: ReturnType<typeof setTimeout> | undefined

  watch(keyword, (q) => {
    clearTimeout(timer)
    timer = setTimeout(async () => {
      controller?.abort()                      // 取消上一次請求,避免舊結果覆蓋新結果
      controller = new AbortController()
      loading.value = true
      error.value = null
      try {
        results.value = q ? await fetcher(q, controller.signal) : []
      } catch (e) {
        if ((e as Error).name !== 'AbortError') error.value = '搜尋失敗,請重試'
      } finally {
        loading.value = false
      }
    }, 300)                                    // 300 毫秒防抖
  })

  onScopeDispose(() => { clearTimeout(timer); controller?.abort() })
  return { results, loading, error }
}

同款作品

用這條提示詞做出來的作品;原作者會因此獲得積分

做同款

還沒有同款,來做第一個。

Nathaniel 的更多內容

同主題

同模型

0 條評論

登入 後參與評論

還沒有評論,來搶沙發~