当在 vue.js 中的特定卡片上发生点击功能时,如何应用基于书籍 ID 或卡片 ID 的样式?

Posted

技术标签:

【中文标题】当在 vue.js 中的特定卡片上发生点击功能时,如何应用基于书籍 ID 或卡片 ID 的样式?【英文标题】:How to apply a styles based on book ID or card ID when click function happens on particular card in vue.js? 【发布时间】:2021-09-20 07:19:12 【问题描述】:

我开发了一个页面,负责显示书籍,响应来自后端 API,基于它显示为卡片的响应数据。

每张书卡包含两个按钮部分,第一部分包含添加到袋子和愿望清单按钮(默认情况下它应该是可见的),在第二部分中它包含一个称为添加到袋子的按钮(默认情况下它应该隐藏)。

如果用户点击任何卡片的“添加到袋子”按钮,那么它应该被隐藏(添加到袋子和愿望清单)并仅显示特定点击卡片的添加到袋子按钮。请帮助我限制样式剩余卡片(点击卡片除外)。

这是点击添加到购物袋按钮之前的默认页面

这就是我在单击任何卡片添加到袋子按钮后获得输出的方式,但我只需要在特定点击的卡片上应用样式

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>
              <button v-if="flag" class="btn-grp" type="submit" @click="handlesubmit();Togglebtn();">close</button>
          </div>
          <div class="buttons">
  <!-- This is my button section -->            
  <div class="button-groups">
                  
                  <button type="button"  @click="toggle(book.id);toggleClass(book.id);" v-bind:class="[storeBooks.indexOf(book.id) >-1 ? 'red' : 'blue']" class="AddBag">Add to Bag</button>
                  
                  <button  class="wishlist">wishlist</button>
              </div>
              <!-- v-if="state==false" -->
              <div v-bind:class="[!(storeBooks.indexOf(book.id)) >-1 ? 'blue':'red']" @click="toggle(book.id)" class="AddedBag">
                  <button class="big-btn">Added to Bag</button>
              </div>
          </div>
      </div>
  <!-- <Cart :cardId="clickedCard" v-if="false" /> -->
  </div>
  </template>
  
  <script>
  import service from '../service/User'
  export default 
      data() 
          return 
              isActive:true,
              storeBooks:[],
              result: 0,
              authorPrefix: 'by',
              pricePrefix: 'Rs.',
              defaultStrikePrice: '(2000)',
              buttonValue: 'close',
              flag: true,
              state: true,
              clickedCard: '',
              books: [
                  id: 0,
                  file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
                  name: 'Dont Make me think',
                  author: 'Sai',
                  price: '1500'
              , ]
          
      ,
      methods: 
          toggleClass: function(event)
              this.isActive = !this.isActive;
              return event;
          ,
          toggle (id) 
            this.clickedCard = id;
            const index = this.storeBooks.indexOf(id);
            if(index > -1) this.storeBooks = this.storeBooks.splice(index,1)
            else
              this.storeBooks.add(id)
            ,
          flip() 
              this.state = !this.state;
          ,
          Togglebtn() 
              this.flag = !this.flag;
          ,
          handlesubmit() 
              service.userDisplayBooks().then(response => 
                  this.books.push(...response.data);     
              )
          ,
      
  
  </script>
  
  <style lang="scss" scoped>
      @import "@/styles/DisplayBooks.scss";
  </style>

更改组件代码后我如何获得输出 但实际上我的期望是 [what i need is]3

DisplayBooks.scss

@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: 275px;
    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;


button[type="submit"] 
    border: none;
    padding-left: 65px;
    background: none;
    font-size: 15;

.button-groups
    display:flex;
    margin-top:8px;

.AddBag
    background: #A03037 0% 0% no-repeat padding-box;
    border-radius: 2px;
    opacity: 1;
    width: 93px;
    height: 29px;
    margin-left:20px;
    color: #FFFFFF;
    text-transform: uppercase;
    opacity: 1;
    font-size: small;

.wishlist
    margin-left:4px;
    color: #FFFFFF;
    text-transform: uppercase;
    opacity: 1;
    font-size: small;
    border: 1px solid #7c7a7a;
    border-radius: 2px;
    opacity: 1;
    color: #0A0102;
    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:#FFFFFF;

.red
    background: red;
   
   
.blue
    background: yellow;
    display:none;

【问题讨论】:

以上解释不清楚,请修改一下,以便我们更好理解 @Amaarrockz 感谢您的回复,我更改了解释,请看一下 【参考方案1】:

您目前只有一个布尔值来检查一本书是否添加到购物车中,如果您添加其中任何一个,您会自动触发该类,它将影响所有其他书籍。

您可以简单地通过向您的图书数据添加额外的键来解决此问题,以便您可以使用数组附带的扩展运算符和映射函数检查是否添加了单独的图书:

data  = data.map(item => (...item, isActive: false))

此代码所做的只是获取您的每个书籍对象,并为其添加具有 false 值的 isActive 键。你可以简单地在 html 中使用这个键和 v-show 来显示你喜欢的按钮:

<div class="button-groups" v-show="!book.isActive">
  <button type="button" @click="book.isActive=!book.isActive;" class="AddBag red">Add to Bag</button>
  <button  class="wishlist">wishlist</button>
</div>

<div @click="book.isActive=!book.isActive" class="AddedBag blue" v-show="book.isActive">
  <button class="big-btn">Added to Bag</button>
</div>

通过这种方式,您可以控制要显示的按钮,我建议您更改 isActive 变量的名称,因为这会让人难以理解什么是活动的。

【讨论】:

push 方法后我必须在哪里添加地图功能 ..? 从API获取结果后直接添加即可。只要您在使用数组之前应用此步骤,它就会起作用 在扩展语法区域显示语法错误 你可以试试这个吗:data = data.map(item => (...item, isActive: false)) 它现在没有显示错误但没有得到所需的输出,当我点击任何卡片添加到袋子按钮时它会隐藏并且添加到袋子按钮也隐藏并且主要它适用于所有卡片并显示数据未定义【参考方案2】:

你可以定义一个数组来存储你的组件数据函数中添加了哪张卡片,比如storeBooks, 在storeBooks=[]

toggle = (id) => 
 const index = this.storeBooks.indexOf(id);
 if(index > -1) this.storeBooks = this.storeBooks.splice(index,1)
 else
  this.storeBooks.add(id)
 

在书卡中,您可以 isActive = storeBooks.indexOf(book.id) &gt; -1 设置类

喜欢这个

<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>
              <button v-if="flag" class="btn-grp" type="submit" @click="handlesubmit();Togglebtn();">close</button>
          </div>
          <div class="buttons">
  <!-- This is my button section -->            
  <div class="button-groups">
                  
                  <button type="button"  @click="toggle(book.id);toggleClass(book.id);" v-bind:class="[storeBooks.indexOf(book.id) >-1 ? 'red' : 'blue']" class="AddBag">Add to Bag</button>
                  
                  <button  class="wishlist">wishlist</button>
              </div>
              <!-- v-if="state==false" -->
              <div v-bind:class="[storeBooks.indexOf(book.id) >-1 ? 'blue':'red']" @click="toggle(book.id)" class="AddedBag">
                  <button class="big-btn">Added to Bag</button>
              </div>
          </div>
      </div>
  <!-- <Cart :cardId="clickedCard" v-if="false" /> -->
  </div>
  </template>
  
  <script>
  import service from '../service/User'
  export default 
      data() 
          return 
              isActive:true,
              storeBooks:[],
              result: 0,
              authorPrefix: 'by',
              pricePrefix: 'Rs.',
              defaultStrikePrice: '(2000)',
              buttonValue: 'close',
              flag: true,
              state: true,
              clickedCard: '',
              books: [
                  id: 0,
                  file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
                  name: 'Dont Make me think',
                  author: 'Sai',
                  price: '1500'
              , ]
          
      ,
      methods: 
          toggleClass: function(event)
              this.isActive = !this.isActive;
              return event;
          ,
          toggle (id) 
            this.clickedCard = id;
            const index = this.storeBooks.indexOf(id);
            if(index > -1) this.storeBooks = this.storeBooks.splice(index,1)
            else
              this.storeBooks.add(id)
            ,
          flip() 
              this.state = !this.state;
          ,
          Togglebtn() 
              this.flag = !this.flag;
          ,
          handlesubmit() 
              service.userDisplayBooks().then(response => 
                  this.books.push(...response.data);     
              )
          ,
      
  
  </script>
  
  <style lang="scss" scoped>
      @import "@/styles/DisplayBooks.scss";
  </style>

【讨论】:

感谢您的回答,但有点困惑在哪里添加此答案 ,也许你理解错了一个问题,我需要的是点击任何卡片添加到袋子按钮,然后添加到袋子和愿望清单应该被隐藏并仅在点击时显示添加到袋子按钮 隐藏或显示元素,可以使用storeBooks.indexOf(book.id) &gt;-1来控制。 我只是复制粘贴你的答案,在我的 UI 页面中,我没有添加到袋子按钮,默认情况下添加到袋子按钮是可见的 在你的代码中,storeBooks.indexOf(book.id) &gt;-1 表示显示 ADDED TO BAG,隐藏 ADD TO BAG,使用 !(storeBooks.indexOf(book.id) &gt;-1) 显示 ADD TO BAG

以上是关于当在 vue.js 中的特定卡片上发生点击功能时,如何应用基于书籍 ID 或卡片 ID 的样式?的主要内容,如果未能解决你的问题,请参考以下文章

如何将点击的卡片按钮 id 传递给 vue.js 中的后端 URL 路径?

如何将点击卡片的 id 和卡片内容传递给 vue.js 中的另一个组件?

如何在 vue 上使用 eventBus 触发点击事件?

如何在 Xcode 模拟器上点击特定点

当在 url 中推送查询参数同时保持在同一路径上时,Vue.js 中的“NavigationDuplicated”异常是不是有任何解决方法

当在颤动中点击网格时如何导航到新页面?