首页 > 解决方案 > 如何在 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>


标签: htmlcssvue.js

解决方案


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只有在有人将鼠标悬停在一本书上时才会显示此描述。


推荐阅读