html - 如何在 vue.js 中悬停特定悬停卡时显示内容?
问题描述
我有一个组件负责显示书籍,并且响应来自后端,它工作正常,现在我需要的是当我将鼠标悬停在任何特定的卡片上时,我想显示这样的书籍描述(这个键也出现在响应中来自后端)。如何实现这件事请帮我解决这个问题....
DisplayBooks.vue
<template>
<div class="carddisplay-section">
<div v-for="book in books" :key="book.id" class="card book">
<div class="image-section">
<div class="image-container">
<img v-bind:src="book.file" />
</div>
</div>
<div class="title-section">
{{book.name}}
</div>
<div class="author-section">
by {{book.author}}
</div>
<div class="price-section">
Rs. {{book.price}}<label class="default">(2000)</label>
</div>
<div class="description">
{{book.description}}
</div>
<div class="buttons">
<div class="button-groups" v-if="!addedBooks.includes(book.id)">
<button type="submit" @click="handleCart(book.id);toggle(book.id);addedBooks.push(book.id)" class="AddBag">Add to Bag</button>
<button class="wishlist">wishlist</button>
</div>
<div class="AddedBag" v-else>
<button class="big-btn" @click="removeFromCart(book.id);addedBooks=addedBooks.filter(id=>id!==book.id)">Added to Bag</button>
</div>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default {
mounted() {
service.userDisplayBooks().then(response => {
this.books.push(...response.data);
return response;
})
},
data() {
return {
isActive:true,
result: 0,
authorPrefix: 'by',
pricePrefix: 'Rs.',
defaultStrikePrice: '(2000)',
buttonValue: 'Add to Bag',
buttonWishlist:'wishlist',
buttonAddedBag:'Added to Bag',
flag: true,
state: true,
addedBooks:[],
clickedCard: '',
books: [
]
}
},
watch:{
addedBooks:{
handler(val){
this.$emit('update-books-count',val.length)
},
deep:true
}
},
methods: {
toggleClass: function(event){
this.isActive = !this.isActive;
return event;
},
toggle(id) {
this.clickedCard = id;
console.log(this.clickedCard);
},
flip() {
this.state = !this.state;
},
Togglebtn() {
this.flag = !this.flag;
},
handleCart(bookId){
let userData={
id: bookId,
}
service.userUpdateCart(userData).then(response=>{
return response;
}).catch(error=>{
alert("error while displaying Books");
return error;
})
},
removeFromCart(bookId){
let userData={
id:bookId,
}
service.userRemoveFromCart(userData).then(response=>{
return response;
}).catch(error=>{
alert("error while removing from cart");
return error;
})
}
}
}
</script>
<style lang="scss" scoped>
@import "colors";
.carddisplay-section {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
align-content: space-around;
gap: 10px;
}
.card:hover{
box-shadow:0.6px 0.6px 0.6px 0.6px rgb(173, 206, 206);
}
.card {
margin-top: 55px;
margin-left: 110px;
background:$pink;
width: 235px;
height: 315px;
background: $pale_white 0% 0% no-repeat padding-box;
border: 1px solid $border_clr;
border-radius: 3px;
opacity: 1;
}
.image-section {
width: 233px;
height: 172px;
background: #F5F5F5 0% 0% no-repeat padding-box;
border-radius: 2px 2px 0px 0px;
opacity: 1;
}
img{
margin-left: 67px;
margin-top: 17px;
width: 105px;
height: 135px;
opacity: 1;
border:none;
}
.title-section {
text-align: left;
font: normal normal normal 14px/19px Roboto;
letter-spacing: 0.2px;
color: $light_black;
opacity: 1;
margin-left: 20px;
margin-top: 3px;
width: 130px;
height: 19px;
text-transform: capitalize;
}
.author-section {
text-align: left;
font: normal normal normal 13px/13px Roboto;
letter-spacing: 0px;
color: $light_grey;
opacity: 1;
width: 123px;
height: 13px;
margin-left: 20px;
margin-top: 7px;
}
.price-section {
text-align: left;
font: normal normal bold 12px/16px Roboto;
letter-spacing: 0px;
color: $light_black;
opacity: 1;
margin-left: 20px;
height: 16px;
margin-top: 26px;
display: flex;
justify-content: flex-start;
}
label {
text-decoration-line: line-through;
font: normal normal normal 10px/13px Roboto;
letter-spacing: 0px;
color: $light_grey;
opacity: 1;
width: 36px;
height: 13px;
margin-top: 2.5px;
margin-left: 1em;
}
.price-section button[type="submit"] {
border: none;
padding-left: 65px;
background: none;
font-size: 15;
}
.button-groups{
display:flex;
margin-top:8px;
}
.AddBag{
background: $redish_brown 0% 0% no-repeat padding-box;
border-radius: 2px;
opacity: 1;
width: 93px;
height: 29px;
margin-left:20px;
color: $pale_white;
text-transform: uppercase;
opacity: 1;
font-size: small;
}
.wishlist{
margin-left:4px;
color: $pale_white;
text-transform: uppercase;
opacity: 1;
font-size: small;
border: 1px solid #7c7a7a;
border-radius: 2px;
opacity: 1;
color: $light_black;
width:93px;
}
.big-btn{
width: 191px;
height: 29px;
margin-left:20px;
background: #3371B5 0% 0% no-repeat padding-box;
border-radius: 2px;
opacity: 1;
color:$pale_white;
margin-top:8px;
}
</style>
解决方案
book
您可以在对象内定义附加标志。叫它吧hover
。
在您的数据从后端返回后,您必须将此属性附加到您的书籍中。例如像这样使用简单map
:
mounted() {
service.userDisplayBooks().then(response => {
let data = response.data;
data.map(function(obj) {
obj.hover = false;
return obj;
});
this.books.push(...data);
return response;
})
},
或者以更简洁的方式使用Object.assign
:
mounted() {
service.userDisplayBooks().then(response => {
this.books.push(Object.assign(...response.data, {hover:false}));
return response;
})
},
然后,检查是否有人将鼠标悬停在您可以使用的书上@mouseover
,@mouseleave
如下所示:
<div v-for="book in books" :key="book.id"
class="card book"
@mouseover="book.hover = true"
@mouseleave="book.hover = false">
还有一个选项可以在不hover
事先初始化标志的情况下执行此操作。您可以使用 Lawrence 在评论中建议的方式。
<div v-for="book in books" :key="book.id"
class="card book"
@mouseover="$set(book, 'hover', true)"
@mouseleave="$delete(book, 'hover')">
最后你可以添加v-if
内部描述:
<div class="description" v-if="book.hover">
通过这样做,div
只有在有人将鼠标悬停在一本书上时才会显示此描述。
推荐阅读
- c++ - 何时通过复制/引用传递?
- sql - 如何使用 CASE 语句获取当前日期?
- vba - 输入产品时如何让表单字段自动填写?
- php - 如何从 html 表单编辑我的 config.php 文件
- azure-devops - 如何从 Azure Devops Powershell YAML 获取输出
- java - 如何将 lambda 从 Java 传递给 Kotlin 方法?
- python - 按唯一组数对 Pandas 列进行排序
- javascript - 使用 jsPDF 创建带有 Unicode 的 PDF
- typescript - 无法通过泛型找到扩展类的属性
- c# - _ManageNav 在添加我自己的身份类后不起作用