DeepSeek 助力 Vue 開發:打造絲滑的縮略圖列表(Thumbnail List)

前言:哈嘍,大家好,今天給大家分享一篇文章!并提供具體代碼幫助大家深入理解,徹底掌握!創作不易,如果能幫助到大家或者給大家一些靈感和啟發,歡迎收藏+關注哦 💕

共同探索軟件研發!敬請關注【寶碼香車】
關注描述

csdngif標識

目錄

  • DeepSeek 助力 Vue 開發:打造絲滑的縮略圖列表(Thumbnail List)
    • 📚前言
    • 📚頁面效果
    • 📚指令輸入
      • 屬性定義
        • 數據相關屬性
        • 布局相關屬性
        • 樣式相關屬性
        • 交互相關屬性
      • 事件
      • 其他
    • 📚think
      • 📘組件代碼
    • 📚代碼測試
    • 📚填寫參數后主要代碼
      • 📘定義組件 src\views\ThumbnailListView.vue
    • 📚測試代碼正常跑通,附其他基本代碼
      • 📘編寫路由 src\router\index.js
      • 📘編寫展示入口 src\App.vue
    • 📚頁面效果
    • 📚相關文章


📚📗📕📘📖🕮💡📝🗂???🛠?💻🚀🎉🏗?🌐🖼?🔗📊👉🔖??🌟🔐??·正文開始??·🎥😊🎓📩😺🌈🤝🤖📜📋🔍?🧰?📄📢📈 🙋0??1??2??3??4??5??6??7??8??9??🔟🆗*??#??

DeepSeek 助力 Vue 開發:打造絲滑的縮略圖列表(Thumbnail List)

📚前言

在創意寫作領域,一位小說家也分享了使用 DeepSeek 的奇妙體驗。他在創作一部科幻小說時,遇到了創作瓶頸,故事的情節發展陷入了僵局。于是,他向 DeepSeek 尋求幫助,輸入了小說的背景設定、人物特點和已有的情節框架。DeepSeek 迅速給出了多個富有創意的情節走向和故事轉折建議,這些建議不僅符合小說的整體風格,還為他打開了新的創作思路。他根據 DeepSeek 的建議,對小說進行了重新構思,最終創作出了一部廣受好評的科幻小說。他表示:“DeepSeek 的創意激發能力讓我驚嘆,它就像是一個創意寶庫,總能在我最需要的時候提供新奇的想法。”

📚頁面效果

頁面效果

📚指令輸入

已經創建好了一個基于Vue3的組合式API的項目(Composition API),并能正常運行起來,請幫我用 Vue3的組合式API(Composition API) 生成一個 縮略圖列表(Thumbnail List) 的功能組件,所有代碼都保存在components/ThumbnailList 下的文件夾中。功能組件的script標簽中只有setup屬性,使用普通 JavaScript 實現,不使用TypeScript。
功能要有,如下屬性:

屬性定義

數據相關屬性
  1. items

    • 類型:數組
    • 描述:用于存儲縮略圖列表的數據,數組中的每個元素代表一個縮略圖項,可以包含圖片的 src、標題、描述等信息。
    • 示例[{ src: 'image1.jpg', title: 'Image 1' }, { src: 'image2.jpg', title: 'Image 2' }]
  2. itemKey

    • 類型:字符串
    • 描述:指定 items 數組中每個元素的唯一標識字段,用于 Vue 的 :key 綁定,確保列表渲染的高效性和正確性。
    • 示例:如果 items 數組中的每個元素有一個 id 字段作為唯一標識,則 itemKey 可以設置為 'id'
布局相關屬性
  1. columns

    • 類型:數字
    • 描述:指定縮略圖列表的列數,用于控制布局。
    • 示例3 表示列表將顯示為 3 列。
  2. gutter

    • 類型:數字或字符串
    • 描述:縮略圖項之間的間距,可以是像素值(如 20)或帶有單位的值(如 '20px')。
樣式相關屬性
  1. thumbnailWidth

    • 類型:數字或字符串
    • 描述:指定縮略圖的寬度,可以是像素值(如 100)或帶有單位的值(如 '100px')。
  2. thumbnailHeight

    • 類型:數字或字符串
    • 描述:指定縮略圖的高度,可以是像素值(如 100)或帶有單位的值(如 '100px')。
  3. loadingPlaceholder

    • 類型:字符串
    • 描述:圖片加載過程中顯示的占位圖的 src 地址。
交互相關屬性
  1. selectedIndex

    • 類型:數字
    • 描述:指定當前選中的縮略圖項的索引,用于實現選中狀態的高亮顯示。
  2. disabledIndexes

    • 類型:數組
    • 描述:指定禁用的縮略圖項的索引數組,禁用的項不可點擊。
    • 示例[1, 3] 表示索引為 1 和 3 的縮略圖項被禁用。

事件

  1. click

    • 參數:當前點擊的縮略圖項的數據和索引
    • 描述:當用戶點擊縮略圖項時觸發,可用于實現點擊縮略圖的相關操作,如顯示大圖、跳轉到詳情頁等。
  2. load

    • 參數:當前加載成功的縮略圖項的數據和索引
    • 描述:當縮略圖圖片加載成功時觸發,可用于實現加載成功后的特效或統計加載成功的圖片數量。
  3. error

    • 參數:當前加載失敗的縮略圖項的數據和索引
    • 描述:當縮略圖圖片加載失敗時觸發,可用于顯示加載失敗的提示信息或替換為默認圖片。
  4. select

    • 參數:當前選中的縮略圖項的數據和索引
    • 描述:當縮略圖項被選中時觸發,可用于更新 selectedIndex 屬性或執行其他選中相關的操作。

其他

  1. 響應式設計:考慮使用 CSS 媒體查詢或 Vue 的響應式布局方案,使縮略圖列表在不同屏幕尺寸下都能有良好的顯示效果。
  2. 懶加載:對于大量的縮略圖列表,使用懶加載技術可以提高頁面的加載性能,只在縮略圖進入可視區域時才加載圖片。
  3. 鍵盤導航:支持鍵盤操作,如使用方向鍵選擇縮略圖項,回車鍵觸發點擊事件,提高組件的可訪問性。
  4. 動畫效果:為縮略圖的選中、加載等狀態添加適當的動畫效果,提升用戶體驗。
  5. 自定義插槽:提供自定義插槽,允許用戶自定義縮略圖的內容,如在縮略圖上添加自定義的徽章、標簽等。

你有更好的建議也可以添加,要注明。組件定義好后給出5個及以上的調用示例。
下面是現有目錄
vueAndDeepseek/
├── src/ # 源代碼目錄
│ ├── assets/ # 靜態資源
│ │ ├── base.css
│ │ ├── main.css
│ │ └── logo.svg
│ ├── components/ # 組件目錄
│ │ ├── HelloWorld.vue
│ │ ├── TheWelcome.vue
│ │ ├── WelcomeItem.vue
│ │ ├── Progress/
│ │ │ └── Progress.vue
│ │ ├── Accordion/
│ │ ├── BackToTop/
│ │ ├── Card/
│ │ ├── InfiniteScroll/
│ │ ├── Notification/
│ │ ├── Timeline/
│ │ ├── Switch/
│ │ ├── Tabs/
│ │ ├── Sidebar/
│ │ ├── Breadcrumbs/
│ │ ├── MasonryLayout/
│ │ ├── Rating/
│ │ ├── ColorPicker/
│ │ ├── RightClickMenu/
│ │ ├── RangePicker/
│ │ ├── Navbar/
│ │ ├── FormValidation/
│ │ ├── CopyToClipboard/
│ │ ├── ClickAnimations/
│ │ ├── ThumbnailList/
│ │ ├── DatePicker/
│ │ └── icons/
│ ├── router/ # 路由配置
│ │ └── index.js
│ ├── stores/ # Pinia 狀態管理
│ │ └── counter.js
│ ├── views/ # 頁面組件
│ │ ├── ProgressView.vue
│ │ ├── TabsView.vue
│ │ ├── SwitchView.vue
│ │ ├── TimelineView.vue
│ │ ├── NotificationView.vue
│ │ ├── CardView.vue
│ │ ├── InfiniteScrollView.vue
│ │ ├── BackToTopView.vue
│ │ ├── AccordionView.vue
│ │ ├── SidebarView.vue
│ │ ├── BreadcrumbsView.vue
│ │ ├── MasonryLayoutView.vue
│ │ ├── RatingView.vue
│ │ ├── ColorPickerView.vue
│ │ ├── RightClickMenuView.vue
│ │ ├── RangePickerView.vue
│ │ ├── NavbarView.vue
│ │ ├── FormValidationView.vue
│ │ ├── CopyToClipboardView.vue
│ │ ├── ClickAnimationsView.vue
│ │ ├── ThumbnailListView.vue
│ │ ├── DatePickerView.vue
│ │ └── AboutView.vue
│ ├── App.vue # 根組件
│ └── main.js # 應用入口
├── public/ # 公共資源目錄
├── index.html # HTML 模板
├── package.json # 項目配置
├── vite.config.js # Vite 配置
└── node_modules/ # 依賴包目錄

📚think

好的,我現在需要幫用戶創建一個基于Vue3組合式API的縮略圖列表組件。用戶已經有一個項目,并且希望所有代碼都保存在components/ThumbnailList文件夾下。首先,我需要明確組件的屬性、事件以及其他要求,然后按照這些要求逐步構建組件。

首先,用戶提到的屬性分為數據相關、布局相關、樣式相關和交互相關。數據方面,items數組和itemKey是必須的。布局方面需要處理columns和gutter,可能需要使用CSS Grid或者Flex布局來實現多列。樣式方面,縮略圖的寬高、占位圖等需要處理。交互方面,選中的索引、禁用索引以及各種事件,比如點擊、加載、錯誤、選擇事件。

接下來,我需要考慮組件的結構。可能使用

  • 來構建列表,每個項包含圖片、標題和描述。圖片加載時可能需要懶加載,這里可以用Intersection Observer實現。同時,處理圖片加載成功和失敗的事件,觸發對應的事件。

響應式設計方面,可能需要根據屏幕大小調整列數,或者使用媒體查詢。但用戶提到使用Vue的響應式布局方案,可能需要在組件內部監聽窗口大小變化,動態調整columns屬性?或者讓用戶通過props傳遞不同的columns,然后自己處理媒體查詢?可能需要進一步明確。

懶加載的實現,當圖片進入視口時加載,可以使用vueuse庫中的useIntersectionObserver,或者自己實現。但用戶希望使用普通JavaScript,可能需要自己寫Intersection Observer的邏輯。

鍵盤導航方面,需要處理方向鍵和回車鍵的事件,這可能需要為每個縮略圖項添加tabindex,并監聽keydown事件。選中項的高亮顯示可以通過CSS類來處理。

自定義插槽部分,用戶可能希望替換縮略圖的內容,比如添加徽章或標簽。所以需要在組件中定義插槽,允許用戶自定義內容。

然后,編寫代碼的結構。在ThumbnailList.vue中,使用setup語法,定義props,處理事件。計算每個項的樣式,比如寬度、高度、間距。處理點擊事件,判斷是否禁用,觸發select和click事件。圖片加載時,觸發load事件,失敗時觸發error事件。

樣式部分,使用scoped的style,處理布局的grid,設置列數和間距。可能需要將gutter轉換為像素單位,比如如果是數字,默認加px,如果是字符串,直接使用。縮略圖的寬高同理。

接下來,測試組件是否符合所有屬性和事件的要求。比如,傳遞items數組,是否正確渲染;itemKey是否正確作為key;columns是否正確設置grid的列數;gutter是否作為間距應用;縮略圖的寬高是否生效;占位圖是否在加載時顯示;選中的索引是否高亮;禁用項是否不可點擊;事件是否正確觸發等。

最后,提供調用示例。用戶需要至少5個示例,展示不同的屬性配置,比如基本用法、自定義樣式、禁用項、懶加載、自定義插槽等。每個示例需要展示如何傳遞props,監聽事件,以及可能的數據結構。

可能的注意事項包括:處理props的默認值,比如columns默認可能是3,gutter默認0,thumbnailWidth和Height的默認值如何處理;是否需要將數字轉換為像素單位;disabledIndexes的數組如何處理,是否使用includes判斷;鍵盤導航的實現細節,比如如何切換焦點,處理方向鍵事件等。

另外,關于響應式設計,可能需要組件內部根據屏幕寬度調整columns,但用戶可能更希望外部控制,所以可能不需要在組件內部處理,而是由父組件通過媒體查詢或其他方式傳遞不同的columns值。

懶加載的實現可能需要為每個圖片元素添加data-src屬性,然后在進入視口時替換為src。使用Intersection Observer監聽每個圖片元素,當進入視口時加載圖片。這部分需要在onMounted中初始化Observer,并在卸載時斷開連接。

動畫效果方面,可以為選中狀態添加CSS過渡,比如邊框顏色變化,或者縮放效果。可能需要使用transition或animation類。

自定義插槽的位置,可能需要在每個縮略圖項內部提供一個默認插槽,允許用戶覆蓋內容。同時,可能需要暴露項的數據給插槽,使用作用域插槽。

現在,開始編寫組件代碼。首先定義props,使用defineProps函數。然后處理布局的grid樣式,計算每個項的寬度和間距。對于gutter,可能需要將其拆分為水平和垂直間距,或者統一處理為gap。使用CSS grid的gap屬性,將gutter值傳入。比如,如果gutter是20,那么grid-gap: 20px。

縮略圖的寬高可能需要在img標簽的樣式中設置,或者外層容器的尺寸。可能需要將thumbnailWidth和Height轉換為帶有單位的字符串,比如如果是數字,加上px,否則直接使用。

處理圖片加載,使用@load和@error事件,觸發對應的事件。同時,在加載過程中顯示占位圖,直到圖片加載完成。

選中的索引通過比較當前項的索引和selectedIndex,添加選中狀態的類名。禁用項通過判斷索引是否在disabledIndexes數組中,添加禁用樣式,并阻止點擊事件。

鍵盤導航部分,需要為每個項添加tabindex,當獲得焦點時,監聽方向鍵和回車鍵。例如,按下右箭頭時,移動到下一個項,超出時循環或停止。回車鍵觸發點擊事件。這部分可能需要為每個項添加ref,并在鍵盤事件中切換焦點。

自定義插槽部分,在組件中預留,并將項的數據作為作用域傳遞,比如:item="item"和:index=“index”,讓用戶可以在插槽中訪問。

最后,編寫示例代碼,展示不同的使用場景,包括基本用法、自定義樣式、禁用項、事件處理、懶加載和插槽自定義。

可能遇到的問題包括:CSS grid布局在不同瀏覽器中的兼容性,但現代瀏覽器應該都支持。懶加載的性能問題,需要合理配置Intersection Observer的root和threshold。鍵盤導航的處理,確保焦點正確切換,并且不會與其他組件沖突。

綜上所述,需要分步驟構建組件,處理每個屬性和事件,確保功能完整,同時代碼結構清晰,符合Vue3組合式API的最佳實踐。

📘組件代碼

根據你的需求,我為你創建了一個功能完善的縮略圖列表組件。以下是完整的實現方案:

<!-- components/ThumbnailList/ThumbnailList.vue -->
<template><ul class="thumbnail-list":style="{gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,gap: typeof gutter === 'number' ? `${gutter}px` : gutter}"><liv-for="(item, index) in items":key="item[itemKey]"class="thumbnail-item":class="{'selected': index === selectedIndex,'disabled': disabledIndexes.includes(index)}":style="{width: typeof thumbnailWidth === 'number' ? `${thumbnailWidth}px` : thumbnailWidth,height: typeof thumbnailHeight === 'number' ? `${thumbnailHeight}px` : thumbnailHeight}"@click="handleClick(item, index)"@keydown="handleKeyDown($event, index)"tabindex="0"><!-- 自定義插槽 --><slot v-if="$slots.default" :item="item" :index="index"></slot><div v-else class="thumbnail-content"><div class="image-wrapper"><img:src="loadingPlaceholder":data-src="item.src":alt="item.title"class="thumbnail-image"@load="handleImageLoad(item, index)"@error="handleImageError(item, index)"ref="imageRefs"/></div><div v-if="item.title" class="thumbnail-title">{{ item.title }}</div><div v-if="item.description" class="thumbnail-description">{{ item.description }}</div></div></li></ul>
</template><script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'const props = defineProps({items: {type: Array,required: true},itemKey: {type: String,default: 'id'},columns: {type: Number,default: 3},gutter: {type: [Number, String],default: 10},thumbnailWidth: {type: [Number, String],default: 200},thumbnailHeight: {type: [Number, String],default: 150},loadingPlaceholder: String,selectedIndex: {type: Number,default: -1},disabledIndexes: {type: Array,default: () => []}
})const emit = defineEmits(['click', 'load', 'error', 'select'])const imageRefs = ref([])
let observer = null// 懶加載處理
onMounted(() => {if ('IntersectionObserver' in window) {observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.targetimg.src = img.dataset.srcobserver.unobserve(img)}})})imageRefs.value.forEach(img => observer.observe(img))} else {// 瀏覽器不支持時直接加載所有圖片imageRefs.value.forEach(img => {img.src = img.dataset.src})}
})onBeforeUnmount(() => {if (observer) observer.disconnect()
})const handleClick = (item, index) => {if (props.disabledIndexes.includes(index)) returnemit('click', { item, index })emit('select', { item, index })
}const handleKeyDown = (e, index) => {if (props.disabledIndexes.includes(index)) returnconst itemsCount = props.items.lengthswitch(e.key) {case 'ArrowRight':focusItem((index + 1) % itemsCount)breakcase 'ArrowLeft':focusItem((index - 1 + itemsCount) % itemsCount)breakcase 'Enter':handleClick(props.items[index], index)break}
}const focusItem = (index) => {const items = document.querySelectorAll('.thumbnail-item')if (items[index]) items[index].focus()
}const handleImageLoad = (item, index) => {emit('load', { item, index })
}const handleImageError = (item, index) => {emit('error', { item, index })
}
</script><style scoped>
.thumbnail-list {display: grid;list-style: none;padding: 0;margin: 0;
}.thumbnail-item {position: relative;cursor: pointer;transition: transform 0.2s ease, box-shadow 0.2s ease;overflow: hidden;background: #f5f5f5;
}.thumbnail-item:hover {transform: translateY(-5px);box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}.thumbnail-item.selected {outline: 2px solid #2196f3;outline-offset: 2px;
}.thumbnail-item.disabled {opacity: 0.5;cursor: not-allowed;pointer-events: none;
}.image-wrapper {position: relative;width: 100%;height: 80%;overflow: hidden;
}.thumbnail-image {width: 100%;height: 100%;object-fit: cover;transition: opacity 0.3s ease;
}.thumbnail-image[data-src] {opacity: 0;
}.thumbnail-image.loaded {opacity: 1;
}.thumbnail-title {padding: 8px;font-weight: bold;text-align: center;
}.thumbnail-description {padding: 0 8px 8px;font-size: 0.9em;text-align: center;color: #666;
}@media (max-width: 768px) {.thumbnail-list {grid-template-columns: repeat(2, 1fr) !important;}
}@media (max-width: 480px) {.thumbnail-list {grid-template-columns: 1fr !important;}
}
</style>

以下是5個使用示例:

<!-- 基本用法 -->
<ThumbnailList:items="[{ id: 1, src: 'image1.jpg', title: 'Nature' },{ id: 2, src: 'image2.jpg', title: 'City' }]"item-key="id"@click="handleClick"
/><!-- 自定義尺寸和間距 -->
<ThumbnailList:items="items":columns="4":gutter="20"thumbnail-width="250"thumbnail-height="200"
/><!-- 禁用項和選中狀態 -->
<ThumbnailList:items="items":selected-index="selectedIndex":disabled-indexes="[0, 2]"@select="handleSelect"
/><!-- 懶加載和占位符 -->
<ThumbnailList:items="lazyItems"loading-placeholder="/placeholder.jpg"
/><!-- 自定義內容插槽 -->
<ThumbnailList :items="items"><template #default="{ item }"><div class="custom-thumbnail"><img :src="item.src" /><div class="badge">{{ item.category }}</div></div></template>
</ThumbnailList>

額外建議和特性說明:

  1. 性能優化:內置了Intersection Observer實現的懶加載
  2. 無障礙支持:支持鍵盤導航(方向鍵切換,回車觸發點擊)
  3. 響應式設計:內置移動端響應式布局
  4. 動畫效果:懸停浮動效果和加載漸顯動畫
  5. 錯誤處理:圖片加載失敗會自動保留占位圖
  6. 樣式擴展:通過CSS變量可以自定義主題色等樣式

使用建議:

  1. 對于大數據量的列表建議搭配虛擬滾動使用
  2. 可以通過CSS變量覆蓋默認樣式
  3. 推薦使用WebP格式圖片優化加載性能
  4. 復雜交互場景可以使用作用域插槽完全自定義內容

📚代碼測試

運行正常,代碼示例中需要自己填一些參數

📚填寫參數后主要代碼

📘定義組件 src\views\ThumbnailListView.vue

<template><div class="thumbnail-list-demo"><h2>縮略圖列表示例</h2><!-- 示例1:基本用法 --><section class="demo-section"><h3>基本用法</h3><!-- 基本用法 --><ThumbnailList:items="[{ id: 1, src: 'https://picsum.photos/300/200?random=1', title: 'Nature' },{ id: 2, src: 'https://picsum.photos/300/200?random=2', title: 'City' }]"thumbnail-width="250"item-key="id"@click="handleClick"/></section><!-- 示例2:自定義尺寸和間距 --><section class="demo-section"><h3>自定義尺寸和間距</h3><ThumbnailList:items="items":columns="4":gutter="20"thumbnail-width="250"thumbnail-height="200"/></section><!-- 示例3:選中和禁用狀態 --><section class="demo-section"><h3>選中和禁用狀態</h3><ThumbnailList:items="items"thumbnail-width="250":selected-index="selectedIndex":disabled-indexes="[0, 2]"@select="handleSelect"/></section><!-- 示例4:懶加載和占位圖 --><section class="demo-section"><h3>懶加載和占位圖</h3><ThumbnailList:items="lazyItems":gutter="20"thumbnail-width="250"loading-placeholder="/placeholder.jpg"/></section><!-- 示例5:自定義插槽 --><section class="demo-section"><h3>自定義插槽</h3><ThumbnailList:items="items":columns="3":gutter="20"thumbnail-width="250"><template #default="{ item }"><div class="custom-thumbnail"><img :src="item.src" :alt="item.title"><div class="custom-overlay"><h4>{{ item.title }}</h4><p>{{ item.description }}</p></div></div></template></ThumbnailList></section></div>
</template><script setup>
import { ref } from 'vue'
import ThumbnailList from '../components/ThumbnailList/ThumbnailList.vue'// 圖片數據
const items = ref([{id: 1,src: 'https://picsum.photos/300/200?random=3',title: '自然風光',description: '美麗的自然景觀'},{id: 2,src: 'https://picsum.photos/300/200?random=4',title: '城市建筑',description: '現代都市風貌'},{id: 3,src: 'https://picsum.photos/300/200?random=5',title: '生活場景',description: '日常生活瞬間'},{id: 4,src: 'https://picsum.photos/300/200?random=6',title: '藝術設計',description: '創意藝術作品'}
])// 懶加載示例數據
const lazyItems = ref([{id: 5,src: 'https://picsum.photos/300/200?random=7',title: '懶加載圖片1',description: '延遲加載示例'},{id: 6,src: 'https://picsum.photos/300/200?random=8',title: '懶加載圖片2',description: '延遲加載示例'},{id: 7,src: 'https://picsum.photos/300/200?random=9',title: '懶加載圖片3',description: '延遲加載示例'}
])// 選中狀態
const selectedIndex = ref(1)// 事件處理函數
const handleClick = (event) => {console.log('點擊縮略圖:', event)
}const handleSelect = (event) => {console.log('選擇縮略圖:', event)selectedIndex.value = event.index
}const handleImageLoad = (event) => {console.log('圖片加載成功:', event)
}const handleImageError = (event) => {console.log('圖片加載失敗:', event)
}
</script><style scoped>
.thumbnail-list-demo {padding: 20px;max-width: 1200px;margin: 0 auto;
}h2 {color: #2c3e50;margin-bottom: 30px;text-align: center;
}.demo-section {margin-bottom: 40px;padding: 20px;border: 1px solid #ebeef5;border-radius: 8px;background-color: #fff;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}h3 {color: #2c3e50;margin-bottom: 20px;font-size: 18px;
}/* 自定義縮略圖樣式 */
.custom-thumbnail {position: relative;width: 100%;height: 100%;overflow: hidden;border-radius: 8px;
}.custom-thumbnail img {width: 100%;height: 100%;object-fit: cover;transition: transform 0.3s ease;
}.custom-thumbnail:hover img {transform: scale(1.1);
}.custom-overlay {position: absolute;bottom: 0;left: 0;right: 0;padding: 15px;background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);color: white;transform: translateY(100%);transition: transform 0.3s ease;
}.custom-thumbnail:hover .custom-overlay {transform: translateY(0);
}.custom-overlay h4 {margin: 0 0 5px 0;font-size: 16px;
}.custom-overlay p {margin: 0;font-size: 14px;opacity: 0.8;
}
</style>

📚測試代碼正常跑通,附其他基本代碼

  • 添加路由
  • 頁面展示入口

📘編寫路由 src\router\index.js

\router\index.js

import { createRouter, createWebHistory } from 'vue-router'
import RightClickMenuView from '../views/RightClickMenuView.vue'
import RangePickerView from '../views/RangePickerView.vue'const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',name: 'progress',component:  () => import('../views/ProgressView.vue'),},{path: '/tabs',name: 'tabs',// route level code-splitting// this generates a separate chunk (About.[hash].js) for this route// which is lazy-loaded when the route is visited.// 標簽頁(Tabs)component: () => import('../views/TabsView.vue'),},{path: '/accordion',name: 'accordion',// 折疊面板(Accordion)component: () => import('../views/AccordionView.vue'),},{path: '/timeline',name: 'timeline',// 時間線(Timeline)component: () => import('../views/TimelineView.vue'),},{path: '/backToTop',name: 'backToTop',component: () => import('../views/BackToTopView.vue')},{path: '/notification',name: 'notification',component: () => import('../views/NotificationView.vue')},{path: '/card',name: 'card',component: () => import('../views/CardView.vue')},{path: '/infiniteScroll',name: 'infiniteScroll',component: () => import('../views/InfiniteScrollView.vue')},{path: '/switch',name: 'switch',component: () => import('../views/SwitchView.vue')},{path: '/sidebar',name: 'sidebar',component: () => import('../views/SidebarView.vue')},{path: '/breadcrumbs',name: 'breadcrumbs',component: () => import('../views/BreadcrumbsView.vue')},{path: '/masonryLayout',name: 'masonryLayout',component: () => import('../views/MasonryLayoutView.vue')},{path: '/rating',name: 'rating',component: () => import('../views/RatingView.vue')},{path: '/datePicker',name: 'datePicker',component: () => import('../views/DatePickerView.vue')},{path: '/colorPicker',name: 'colorPicker',component: () => import('../views/ColorPickerView.vue')},{path: '/rightClickMenu',name: 'rightClickMenu',component: RightClickMenuView},{path: '/rangePicker',name: 'rangePicker',component: () => import('../views/RangePickerView.vue')},{path: '/navbar',name: 'navbar',component: () => import('../views/NavbarView.vue')},{path: '/formValidation',name: 'formValidation',component: () => import('../views/FormValidationView.vue')},{path: '/copyToClipboard',name: 'copyToClipboard',component: () => import('../views/CopyToClipboardView.vue')},{path: '/clickAnimations',name: 'clickAnimations',component: () => import('../views/ClickAnimationsView.vue')},{path: '/thumbnailList',name: 'thumbnailList',component: () => import('../views/ThumbnailListView.vue')}],
})export default router

📘編寫展示入口 src\App.vue

 src\App.vue

<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script><template><header><img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /><div class="wrapper"><HelloWorld msg="You did it!" /><nav><RouterLink to="/">Progress</RouterLink><RouterLink to="/tabs">Tabs</RouterLink><RouterLink to="/accordion">Accordion</RouterLink><RouterLink to="/timeline">Timeline</RouterLink><RouterLink to="/backToTop">BackToTop</RouterLink><RouterLink to="/notification">Notification</RouterLink><RouterLink to="/card">Card</RouterLink><RouterLink to="/infiniteScroll">InfiniteScroll</RouterLink><RouterLink to="/switch">Switch</RouterLink><RouterLink to="/sidebar">Sidebar</RouterLink><RouterLink to="/breadcrumbs">Breadcrumbs</RouterLink><RouterLink to="/masonryLayout">MasonryLayout</RouterLink><RouterLink to="/rating">Rating</RouterLink><RouterLink to="/datePicker">DatePicker</RouterLink><RouterLink to="/colorPicker">ColorPicker</RouterLink><RouterLink to="/rightClickMenu">RightClickMenu</RouterLink><RouterLink to="/rangePicker">RangePicker</RouterLink><RouterLink to="/navbar">Navbar</RouterLink><RouterLink to="/formValidation">FormValidation</RouterLink><RouterLink to="/copyToClipboard">CopyToClipboard</RouterLink><RouterLink to="/clickAnimations">ClickAnimations</RouterLink><RouterLink to="/thumbnailList">ThumbnailList</RouterLink></nav></div></header><RouterView />
</template><style scoped>
header {line-height: 1.5;max-height: 100vh;
}.logo {display: block;margin: 0 auto 2rem;
}nav {width: 100%;font-size: 12px;text-align: center;margin-top: 2rem;
}nav a.router-link-exact-active {color: var(--color-text);
}nav a.router-link-exact-active:hover {background-color: transparent;
}nav a {display: inline-block;padding: 0 1rem;border-left: 1px solid var(--color-border);
}nav a:first-of-type {border: 0;
}@media (min-width: 1024px) {header {display: flex;place-items: center;padding-right: calc(var(--section-gap) / 2);}.logo {margin: 0 2rem 0 0;}header .wrapper {display: flex;place-items: flex-start;flex-wrap: wrap;}nav {text-align: left;margin-left: -1rem;font-size: 1rem;padding: 1rem 0;margin-top: 1rem;}
}
</style>

📚頁面效果

頁面效果

📚相關文章

?

———— 相 關 文 章 ————

?

  1. 0基礎3步部署自己的DeepSeek安裝步驟

  2. DeepSeek 助力 Vue 開發:打造絲滑的步驟條(Step bar)https://blog.csdn.net/qq_33650655/article/details/145560497

  3. DeepSeek 助力 Vue 開發:打造絲滑的進度條(Progress Bar)https://blog.csdn.net/qq_33650655/article/details/145577034

  4. 自己部署 DeepSeek 助力 Vue 開發:打造絲滑的標簽頁(Tabs)https://blog.csdn.net/qq_33650655/article/details/145587999

  5. 自己部署 DeepSeek 助力 Vue 開發:打造絲滑的折疊面板(Accordion)https://blog.csdn.net/qq_33650655/article/details/145590404

  6. 自己部署 DeepSeek 助力 Vue 開發:打造絲滑的時間線(Timeline )https://blog.csdn.net/qq_33650655/article/details/145597372

  7. DeepSeek 助力 Vue 開發:打造絲滑的返回頂部按鈕(Back to Top)https://blog.csdn.net/qq_33650655/article/details/145615550

  8. DeepSeek 助力 Vue 開發:打造絲滑的通知欄(Notification Bar)https://blog.csdn.net/qq_33650655/article/details/145620055

  9. DeepSeek 助力 Vue 開發:打造絲滑的卡片(Card)https://blog.csdn.net/qq_33650655/article/details/145634564

  10. DeepSeek 助力 Vue 開發:打造絲滑的無限滾動(Infinite Scroll)https://blog.csdn.net/qq_33650655/article/details/145638452

  11. DeepSeek 助力 Vue 開發:打造絲滑的開關切換(Switch)https://blog.csdn.net/qq_33650655/article/details/145644151

  12. DeepSeek 助力 Vue 開發:打造絲滑的側邊欄(Sidebar)https://blog.csdn.net/qq_33650655/article/details/145654204

  13. DeepSeek 助力 Vue 開發:打造絲滑的面包屑導航(Breadcrumbs)https://blog.csdn.net/qq_33650655/article/details/145656895

  14. DeepSeek 助力 Vue 開發:打造絲滑的瀑布流布局(Masonry Layout)https://blog.csdn.net/qq_33650655/article/details/145663699

  15. DeepSeek 助力 Vue 開發:打造絲滑的評分組件(Rating)https://blog.csdn.net/qq_33650655/article/details/145664576

  16. DeepSeek 助力 Vue 開發:打造絲滑的日期選擇器(Date Picker),未使用第三方插件 https://blog.csdn.net/qq_33650655/article/details/145673279

  17. DeepSeek 助力 Vue 開發:打造絲滑的顏色選擇器(Color Picker)https://blog.csdn.net/qq_33650655/article/details/145689522

  18. DeepSeek 助力 Vue 開發:打造絲滑的右鍵菜單(RightClickMenu)https://blog.csdn.net/qq_33650655/article/details/145706658

  19. DeepSeek 助力 Vue 開發:打造絲滑的范圍選擇器(Range Picker)https://blog.csdn.net/qq_33650655/article/details/145713572

  20. DeepSeek 助力 Vue 開發:打造絲滑的導航欄(Navbar)https://blog.csdn.net/qq_33650655/article/details/145732421

  21. DeepSeek 助力 Vue 開發:打造絲滑的表單驗證(Form Validation)https://blog.csdn.net/qq_33650655/article/details/145735582

  22. DeepSeek 助力 Vue 開發:打造絲滑的復制到剪貼板(Copy to Clipboard)https://blog.csdn.net/qq_33650655/article/details/145739569

  23. DeepSeek 助力 Vue 開發:打造絲滑的點擊動畫(Click Animations)https://blog.csdn.net/qq_33650655/article/details/145766184

到此這篇文章就介紹到這了,更多精彩內容請關注本人以前的文章或繼續瀏覽下面的文章,創作不易,如果能幫助到大家,希望大家多多支持寶碼香車~💕,若轉載本文,一定注明本文鏈接。


整理不易,點贊關注寶碼香車

更多專欄訂閱推薦:
👍 html+css+js 絢麗效果
💕 vue
?? Electron
?? js
📝 字符串
?? 時間對象(Date())操作

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896010.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896010.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896010.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DeepSeek寫俄羅斯方塊手機小游戲

DeepSeek寫俄羅斯方塊手機小游戲 提問 根據提的要求&#xff0c;讓DeepSeek整理的需求&#xff0c;進行提問&#xff0c;內容如下&#xff1a; 請生成一個包含以下功能的可運行移動端俄羅斯方塊H5文件&#xff1a; 核心功能要求 原生JavaScript實現&#xff0c;適配手機屏幕 …

百問網(100ask)的IMX6ULL開發板的以太網控制器(MAC)與物理層(PHY)芯片(LAN8720A)連接的原理圖分析(包含各引腳說明以及工作原理)

前言 本博文承接博文 https://blog.csdn.net/wenhao_ir/article/details/145663029 。 本博文和博文 https://blog.csdn.net/wenhao_ir/article/details/145663029 的目錄是找出百問網(100ask)的IMX6ULL開發板與NXP官方提供的公板MCIMX6ULL-EVK(imx6ull14x14evk)在以太網硬件…

QT開發技術 【opencv圖片裁剪,平均哈希相似度判斷,以及獲取游戲窗口圖片】

一、圖片裁剪 int CJSAutoWidget::GetHouseNo(cv::Mat matMap) {cv::imwrite(m_strPath "/Data/map.png", matMap);for (int i 0; i < 4; i){for (int j 0; j < 6; j){// 計算當前子區域的矩形cv::Rect roi(j * 20, i * 17, 20, 17);// 提取子區域cv::Mat …

TiDB 是一個分布式 NewSQL 數據庫

TiDB 是一個分布式 NewSQL 數據庫。它支持水平彈性擴展、ACID 事務、標準 SQL、MySQL 語法和 MySQL 協議&#xff0c;具有數據強一致的高可用特性&#xff0c;是一個不僅適合 OLTP 場景還適合 OLAP 場景的混合數據庫。 TiDB是 PingCAP公司自主設計、研發的開源分布式關系型數據…

請解釋 Vue 中的生命周期鉤子,不同階段觸發的鉤子函數及其用途是什么?

vue生命周期鉤子詳解&#xff08;Vue 3版本&#xff09; 一、生命周期階段劃分 Vue組件的生命周期可分為四大階段&#xff0c;每個階段對應特定鉤子函數&#xff1a; 創建階段&#xff1a;初始化實例并準備數據掛載階段&#xff1a;將虛擬DOM渲染為真實DOM更新階段&#xff…

計算機專業知識【深入理解子網中的特殊地址:為何 192.168.0.1 和 192.168.0.255 不能隨意分配】

在計算機網絡的世界里&#xff0c;IP 地址是設備進行通信的關鍵標識。對于常見的子網&#xff0c;如 192.168.0.0/24&#xff0c;我們可能會疑惑為何某些地址不能分配給主機使用。接下來&#xff0c;我們就以 192.168.0.0/24 為例&#xff0c;詳細解釋為何 192.168.0.1 和 192.…

軟件架構設計:軟件工程

一、軟件工程概述 軟件工程的定義 軟件工程是應用系統化、規范化、可量化的方法開發、運行和維護軟件。 軟件工程的目標 提高軟件質量、降低開發成本、縮短開發周期。 軟件生命周期 瀑布模型&#xff1a;需求分析→設計→編碼→測試→維護。迭代模型&#xff1a;分階段迭代開…

mysql 學習15 SQL優化,插入數據優化,主鍵優化,order by優化,group by 優化,limit 優化,count 優化,update 優化

插入數據優化&#xff0c; insert 優化&#xff0c; 批量插入&#xff08;一次不超過1000條&#xff09; 手動提交事務 主鍵順序插入 load 從本地一次插入大批量數據&#xff0c; 登陸時 mysql --local-infile -u root -p load data local infile /root/sql1.log into table tb…

達夢數據庫針對慢SQL,收集統計信息清除執行計劃緩存

前言&#xff1a;若遇到以下場景&#xff0c;大概率是SQL走錯了執行計劃&#xff1a; 1、一條SQL在頁面上查詢特別慢&#xff0c;但拿到數據庫終端執行特別快 2、一條SQL在某種檢索條件下查詢特別慢&#xff0c;但拿到數據庫終端執行特別快 此時&#xff0c;可以嘗試按照下述步…

使用JWT實現微服務鑒權

目錄 一、微服務鑒權 1、思路分析 2、系統微服務簽發token 3、網關過濾器驗證token 4、測試鑒權功能 前言&#xff1a; 隨著微服務架構的廣泛應用&#xff0c;服務間的鑒權與安全通信成為系統設計的核心挑戰之一。傳統的集中式會話管理在分布式場景下面臨性能瓶頸和擴展性…

廣西壯族自治區園區投促中心黨委書記陶德文率團到訪深蘭科技

2月16日&#xff0c;廣西壯族自治區園區投促中心黨委書記、主任&#xff0c;自治區園區辦黨組成員陶德文率團來到深蘭科技集團上海總部考察調研&#xff0c;并與深蘭科技集團創始人、董事長陳海波等集團管理層座談交流&#xff0c;雙方圍繞深蘭科技人工智能項目落地廣西的相關事…

基于UnrealEngine(UE5)的太空探索

視頻部分可參見&#xff1a;https://www.bilibili.com/video/BV1JWA8eSEVg/ 中國 天宮號 空間站 人造衛星可視化 星鏈衛星可視化 小行星分布及運動軌跡可視化 月球基地 可視化 八大行星軌道 太陽系宜居帶可視化 阿波羅8號拍攝的地球升起 谷神星模型及軌跡可視化 星座可視化 十…

WLAN無線2.4G/5G頻段劃分和可用信道

互聯網各領域資料分享專區(不定期更新)&#xff1a; Sheet

使用 OpenTelemetry 和 Langtrace 的 Elastic 分發跟蹤基于 RAG 的聊天機器人

作者&#xff1a;來自 Elastic Bahubali Shetti 如何使用 Elastic 觀察基于 OpenAI RAG 的應用程序。使用 Langtrace 對應用程序進行檢測&#xff0c;收集日志、跟蹤、指標&#xff0c;并了解 LLM 在 Kubernetes 上使用 OpenTelemetry 的 Elastic Distributions 的運行情況。 目…

基于機器學習的水文數據采集預測與可視化分析系統

【機器學習】基于機器學習的水文數據采集預測與可視化分析系統&#xff08;完整系統源碼開發筆記詳細部署教程&#xff09;? 目錄 一、項目簡介二、項目界面展示三、項目視頻展示 一、項目簡介 系統采用Python及Flask框架構建Web服務端&#xff0c;結合PyMySQL與MySQL實現數據…

三甲醫院網絡架構與安全建設實戰

一、設計目標 實現醫療業務網/衛生專網/互聯網三網隔離 滿足等保2.0三級合規要求 保障PACS影像系統低時延傳輸 實現醫療物聯網統一接入管控 二、全網拓撲架構 三、網絡分區與安全設計 IP/VLAN規劃表 核心業務配置&#xff08;華為CE6865&#xff09; interface 100G…

MySQL如何解決幻讀?

目錄 一、什么是幻讀&#xff1f; 1.1 幻讀的定義 1.2 幻讀的示例 1.3 幻讀產生的原因&#xff1f; 1.4?讀已提交&#xff08;Read Committed&#xff09; 1.4.1 確定事務等級 1.4.2 非鎖定讀取 準備 示例 結論 1.4.3 鎖定讀取 準備 示例 分析 結論 1.5?可重…

Openssl之SM2加解密命令

### 1. 生成 SM2 私鑰openssl genpkey -algorithm EC \-pkeyopt ec_paramgen_curve:sm2 \-out sm2_private_key.pem### 2. 從私鑰導出 SM2 公鑰openssl pkey -in sm2_private_key.pem \-pubout \-out sm2_public_key.pem### 3. 使用 SM2 公鑰加密openssl pkeyutl -encrypt \-pu…

【含文檔+PPT+源碼】基于Python的圖書推薦系統的設計與實現

課程簡介&#xff1a; 本課程演示的是一款基于python的圖書推薦系統的設計與實現&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Python學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行…