vue實(shí)現(xiàn)卡片遮罩層交互式功能
前言
在前端開發(fā)中,卡片遮罩層是一種常見的交互設(shè)計(jì)元素,用于強(qiáng)調(diào)某個(gè)區(qū)域或內(nèi)容,并提供用戶操作的入口。本文將帶大家在
vue
中結(jié)合實(shí)際案例實(shí)現(xiàn)此功能。
實(shí)現(xiàn)效果
完整代碼
html
<template> <!-- 主容器 --> <div class="box"> <div class="card" @click="cardDetails(index)" @mousedown.prevent="startLongPress($event, index)" @mouseup="stopLongPress" @mouseleave="stopLongPress" v-for="(item, index) in list" :key="index" ref="cardRef" > <!-- 卡片內(nèi)容 --> <div class="content"> <div class="cardImg"> <img :src="item.imgUrl" alt="" /> </div> <div class="introduce">{{ item.name }}</div> </div> <!-- 長按時(shí)顯示的遮罩層 --> <div v-show="item.showOverlay" class="overlay" :class="{ 'expand-animation': item.showOverlay }" @click.stop > <div class="buttonCon"> <div v-for="(shadeItem, shadeIndex) in shadeList" :key="shadeIndex" @click="onShade(shadeItem.title)" > {{ shadeItem.title }} </div> </div> <span class="close" @click="closeOverlay($event, index)">×</span> </div> </div> </div> </template>
js
<script> export default { data() { return { shadeList: [ { title: "商品不感興趣" }, { title: "不想看到此類商品" }, { title: "已經(jīng)買了" }, { title: "圖片引起不適" }, { title: "更多..." }, ], longPressTimer: null, // 用于存儲(chǔ)長按計(jì)時(shí)器 list: [ { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, { imgUrl: "https://img01.yzcdn.cn/vant/cat.jpeg", name: "xxxxxxxxxxxxxxxxxxxxxxx", showOverlay: false, }, ], }; }, mounted() { // 監(jiān)聽窗口滾動(dòng) window.addEventListener("scroll", this.closeAllOverlaysOnScroll); }, // 實(shí)例銷毀前移除監(jiān)聽窗口的滾動(dòng) beforeDestroy() { window.removeEventListener("scroll", this.closeAllOverlaysOnScroll); }, methods: { // 滾動(dòng)時(shí)關(guān)閉遮罩層 closeAllOverlaysOnScroll() { this.list.forEach((item) => { this.$set(item, "showOverlay", false); }); }, // 開始長按事件 startLongPress(event, index) { event.preventDefault(); event.stopPropagation(); this.closeOtherOverlays(index); this.longPressTimer = setTimeout(() => { this.list[index].showOverlay = true; document.addEventListener("click", this.checkClickOutside); }, 100); }, closeOtherOverlays(index) { this.list.forEach((item, i) => { if (i !== index) { item.showOverlay = false; } }); }, // 點(diǎn)擊卡片詳情 cardDetails(index) { if (!this.list[index].showOverlay) { console.log("點(diǎn)擊卡片"); } }, // 結(jié)束長按事件 stopLongPress() { clearTimeout(this.longPressTimer); document.removeEventListener("click", this.checkClickOutside); }, // 關(guān)閉遮罩層 closeOverlay(event, index) { event.stopPropagation(); // 阻止事件冒泡 this.$set(this.list[index], "showOverlay", false); // 關(guān)閉當(dāng)前卡片的遮罩層 document.removeEventListener("click", this.checkClickOutside); }, // 檢查點(diǎn)擊區(qū)域是否在遮罩層外 checkClickOutside(event) { // 遍歷所有卡片,關(guān)閉非點(diǎn)擊卡片的遮罩層 this.list.forEach((item, index) => { if (!this.$refs.cardRef[index].contains(event.target)) { this.$set(item, "showOverlay", false); } }); document.removeEventListener("click", this.checkClickOutside); }, // 點(diǎn)擊遮罩層內(nèi)容 onShade(name) { console.log(name); }, }, }; </script>
css
<style scoped lang="less"> .box { font-size: 16px; min-height: 100vh; background: #f0f0f0; padding: 8px; .card { width: 49%; display: inline-block; background-color: white; position: relative; overflow-wrap: break-word; user-select: none; margin-bottom: 10px; border-radius: 8px; .introduce { text-align: justify; overflow: hidden; padding: 0px 6px 6px 6px; font-size: 14px; height: 50px; font-size: 14px; } .cardImg { img { border-top-left-radius: 8px; border-top-right-radius: 8px; width: 100%; height: 120px; } } .overlay { padding: 16px 10px; box-sizing: border-box; border-radius: 8px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(35, 35, 35, 0.8); &.expand-animation { animation: expand 0.3s forwards; } } .buttonCon { font-size: 14px; width: 100%; color: rgb(213, 207, 207); div:not(:last-child) { border-bottom: 1px solid rgb(82, 82, 82); margin-bottom: 8px; } div { padding: 0px 2px 4px 2px; } } .close { position: absolute; top: 2px; right: 8px; font-size: 20px; cursor: pointer; color: white; } } .card:nth-child(even) { margin-left: 2%; } } @keyframes expand { 0% { transform: scale(0); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } </style>
實(shí)現(xiàn)思路
這段代碼實(shí)現(xiàn)了一個(gè)交互式的卡片列表功能,其中每個(gè)卡片包含一個(gè)圖片和一些文字介紹。用戶可以通過點(diǎn)擊卡片來查看詳情,同時(shí)也可以通過長按卡片來顯示一個(gè)遮罩層,遮罩層上有一些操作按鈕,如"商品不感興趣"、"不想看到此類商品"等選項(xiàng)。此外,用戶還可以點(diǎn)擊遮罩層外的區(qū)域來關(guān)閉遮罩層。整體功能類似于一個(gè)商品展示頁面,用戶可以對(duì)商品進(jìn)行不同的操作和反饋。
首先,實(shí)現(xiàn)卡片列表展示功能。通過循環(huán)遍歷一個(gè)包含圖片和文字介紹的數(shù)據(jù)數(shù)組,動(dòng)態(tài)生成多個(gè)卡片組件。每個(gè)卡片組件包含一個(gè)圖片元素和一個(gè)文字介紹元素,通過 vue
的 v-for
指令實(shí)現(xiàn)數(shù)據(jù)綁定,將對(duì)應(yīng)的圖片和文字展示在每個(gè)卡片上。
其次,實(shí)現(xiàn)點(diǎn)擊卡片查看詳情的功能。為每個(gè)卡片組件添加點(diǎn)擊事件監(jiān)聽器,當(dāng)用戶點(diǎn)擊某個(gè)卡片時(shí),觸發(fā)相應(yīng)的事件處理函數(shù),展示該卡片的詳細(xì)信息。這可以通過 vue
的 @click
指令實(shí)現(xiàn),為每個(gè)卡片元素添加點(diǎn)擊事件處理邏輯。
接著,實(shí)現(xiàn)長按卡片顯示遮罩層的功能。在代碼中,為每個(gè)卡片組件添加長按事件監(jiān)聽器,當(dāng)用戶長按某個(gè)卡片時(shí),顯示遮罩層。通過 vue
的 @touchstart
指令監(jiān)聽長按事件,并在事件觸發(fā)時(shí)顯示遮罩層。遮罩層可以是一個(gè)覆蓋在卡片上方的半透明層,用來提供操作按鈕和用戶反饋選項(xiàng)。
在遮罩層上添加操作按鈕,如"商品不感興趣"、"不想看到此類商品"等選項(xiàng)。用戶可以通過點(diǎn)擊這些按鈕來進(jìn)行不同的操作和反饋。通過在遮罩層組件中添加按鈕元素,并為每個(gè)按鈕添加點(diǎn)擊事件處理邏輯來實(shí)現(xiàn)。
最后,實(shí)現(xiàn)點(diǎn)擊遮罩層外的區(qū)域關(guān)閉遮罩層的功能。為遮罩層外的區(qū)域添加點(diǎn)擊事件監(jiān)聽器,當(dāng)用戶點(diǎn)擊遮罩層外的區(qū)域時(shí),關(guān)閉遮罩層。通過 vue
的 @click
指令監(jiān)聽遮罩層外區(qū)域的點(diǎn)擊事件,并在事件觸發(fā)時(shí)關(guān)閉遮罩層。
到此這篇關(guān)于vue實(shí)現(xiàn)卡片遮罩層交互式功能的文章就介紹到這了,更多相關(guān)vue遮罩層內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解
這篇文章主要為大家介紹了Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Vue事件獲取事件對(duì)象之event.currentTarget詳解
這篇文章主要介紹了Vue事件獲取事件對(duì)象之event.currentTarget,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Vue3使用dataV報(bào)錯(cuò)問題的解決方法
這篇文章主要為大家詳細(xì)介紹了Vue3中使用dataV報(bào)錯(cuò)問題的解決方法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11Vue3中的動(dòng)畫過渡實(shí)現(xiàn)技巧分享
在現(xiàn)代的前端開發(fā)中,用戶體驗(yàn)的重要性不言而喻,為了讓應(yīng)用程序更加生動(dòng)和引人注目,動(dòng)畫和過渡效果是必不可少的元素,本文將以 Vue3 為基礎(chǔ),深入探討如何在應(yīng)用程序中實(shí)現(xiàn)動(dòng)畫過渡,以及一些技巧和最佳實(shí)踐,需要的朋友可以參考下2025-01-01vue插件--仿微信小程序showModel實(shí)現(xiàn)模態(tài)提示窗功能
這篇文章主要介紹了vue插件--仿微信小程序showModel實(shí)現(xiàn)模態(tài)提示窗,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08vue3實(shí)現(xiàn)el-table分批渲染表格
這篇文章主要為大家詳細(xì)介紹了vue3項(xiàng)目中如何實(shí)現(xiàn)el-table分批渲染表格,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11