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>
<!-- 長(zhǎng)按時(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ǔ)長(zhǎng)按計(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);
});
},
// 開始長(zhǎng)按事件
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é)束長(zhǎng)按事件
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è)圖片和一些文字介紹。用戶可以通過(guò)點(diǎn)擊卡片來(lái)查看詳情,同時(shí)也可以通過(guò)長(zhǎng)按卡片來(lái)顯示一個(gè)遮罩層,遮罩層上有一些操作按鈕,如"商品不感興趣"、"不想看到此類商品"等選項(xiàng)。此外,用戶還可以點(diǎn)擊遮罩層外的區(qū)域來(lái)關(guān)閉遮罩層。整體功能類似于一個(gè)商品展示頁(yè)面,用戶可以對(duì)商品進(jìn)行不同的操作和反饋。
首先,實(shí)現(xiàn)卡片列表展示功能。通過(guò)循環(huán)遍歷一個(gè)包含圖片和文字介紹的數(shù)據(jù)數(shù)組,動(dòng)態(tài)生成多個(gè)卡片組件。每個(gè)卡片組件包含一個(gè)圖片元素和一個(gè)文字介紹元素,通過(guò) 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ì)信息。這可以通過(guò) vue 的 @click 指令實(shí)現(xiàn),為每個(gè)卡片元素添加點(diǎn)擊事件處理邏輯。
接著,實(shí)現(xiàn)長(zhǎng)按卡片顯示遮罩層的功能。在代碼中,為每個(gè)卡片組件添加長(zhǎng)按事件監(jiān)聽器,當(dāng)用戶長(zhǎng)按某個(gè)卡片時(shí),顯示遮罩層。通過(guò) vue 的 @touchstart 指令監(jiān)聽長(zhǎng)按事件,并在事件觸發(fā)時(shí)顯示遮罩層。遮罩層可以是一個(gè)覆蓋在卡片上方的半透明層,用來(lái)提供操作按鈕和用戶反饋選項(xiàng)。
在遮罩層上添加操作按鈕,如"商品不感興趣"、"不想看到此類商品"等選項(xiàng)。用戶可以通過(guò)點(diǎn)擊這些按鈕來(lái)進(jìn)行不同的操作和反饋。通過(guò)在遮罩層組件中添加按鈕元素,并為每個(gè)按鈕添加點(diǎn)擊事件處理邏輯來(lái)實(shí)現(xiàn)。
最后,實(shí)現(xiàn)點(diǎn)擊遮罩層外的區(qū)域關(guān)閉遮罩層的功能。為遮罩層外的區(qū)域添加點(diǎn)擊事件監(jiān)聽器,當(dāng)用戶點(diǎn)擊遮罩層外的區(qū)域時(shí),關(guān)閉遮罩層。通過(guò) 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-02
Vue事件獲取事件對(duì)象之event.currentTarget詳解
這篇文章主要介紹了Vue事件獲取事件對(duì)象之event.currentTarget,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
Vue3使用dataV報(bào)錯(cuò)問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了Vue3中使用dataV報(bào)錯(cuò)問(wèn)題的解決方法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11
Vue3中的動(dòng)畫過(guò)渡實(shí)現(xiàn)技巧分享
在現(xiàn)代的前端開發(fā)中,用戶體驗(yàn)的重要性不言而喻,為了讓應(yīng)用程序更加生動(dòng)和引人注目,動(dòng)畫和過(guò)渡效果是必不可少的元素,本文將以 Vue3 為基礎(chǔ),深入探討如何在應(yīng)用程序中實(shí)現(xiàn)動(dòng)畫過(guò)渡,以及一些技巧和最佳實(shí)踐,需要的朋友可以參考下2025-01-01
vue插件--仿微信小程序showModel實(shí)現(xiàn)模態(tài)提示窗功能
這篇文章主要介紹了vue插件--仿微信小程序showModel實(shí)現(xiàn)模態(tài)提示窗,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
vue3實(shí)現(xiàn)el-table分批渲染表格
這篇文章主要為大家詳細(xì)介紹了vue3項(xiàng)目中如何實(shí)現(xiàn)el-table分批渲染表格,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11

