搜索

首页  >  问答  >  正文

在Vuejs中,当元素被点击时,切换元素的类(或更改样式)

我获取数据的方式有点复杂。我有“tweets”数组,其中存储数据,每条推文都是一张卡片,单击卡片时我成功地更改了样式(markTweet 函数),但每条推文也有回复,显示与推文相同(每个回复都有自己的回复)卡片)。我从服务器获取数据的方式:

let replies = []
for(const tweet of tweets) {
    let reply = await SQL('SELECT * FROM tweet_replies WHERE tweet_replies.conversation_id = ?', tweet.tweet_id)
    replies.push(reply)
}
    
const data = {
    tweets: tweets,
    page: parseInt(currentPage),
    numberOfPages: arr,
    replies
}

然后我在 vue 中有组件。您可以看到回复存储在每条推文中的 tweets 数组中,作为 tweetReplies。 在markReply函数中,我成功地将id添加到数组中。

<template>
  <div class="container-full">
    <div class="tweets-container">
      <div
        v-for="(tweet, i) in tweets"
        :key="tweet.id"
      >
        <div
          class="tweet-card"
          :class="{ selected: tweet.isSelected }"
          @click="markTweet(tweet.tweet_id, i)"
        >
          <div class="text">
            <p
              v-html="tweet.tweet_text"
            >
              {{ tweet.tweet_text }}
            </p>
          </div>
        </div>
        <div class="replies">
          <div
            v-for="(reply, index) in tweet.tweetReplies"
            :key="reply.tweet_id"
            @click="markReply(reply.tweet_id, index)"
          >
            <div class="tweet-card tweet-reply">
              <div class="text">
                <p>
                  {{ reply.tweet_text }}
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import { getUserToken } from '@/auth/auth'
import moment from 'moment'
import { BFormTextarea, BButton, BFormSelect } from 'bootstrap-vue'

export default {
  components: { BFormTextarea, BButton, BFormSelect },
  data() {
    return {
      tweets: [],
      tweetActionIds: [],
      categories: [],
    }
  },
  beforeMount() {
    this.getTweets()
  },
  methods: {
    getTweets() {
      this.tweets = []
      const API_URL = `${this.$server}/api/twitter/tweets`

      const params = {
        token: getUserToken(),
        page: this.$route.query.page,
        newCurrentPage: newCurrent,
      }
      axios.post(API_URL, null, { params }).then(res => {
        this.currentPage = res.data.page
        this.numberOfPages = res.data.numberOfPages

        if (res.data) {
          res.data.tweets.forEach(tweet => {
            const tweetData = {
              id: tweet.id,
              tweet_id: tweet.tweet_id,
              tweet_text: htmlText,
              tweet_text_en: htmlTextEn,
              twitter_name: tweet.twitter_name,
              twitter_username: tweet.twitter_username,
              added_at: moment(String(tweet.added_at)).format(
                'MM/DD/YYYY hh:mm',
              ),
              URL: tweet.URL,
              isSelected: false,
              tweetReplies: [],
            }
            this.tweets.push(tweetData)
          })
          res.data.replies.forEach(reply => {
            reply.forEach(r => {
              this.tweets.forEach(tweet => {
                if (tweet.tweet_id === r.conversation_id) {
                  tweet.tweetReplies.push(r)
                }
              })
            })
          })
        }
      })
    },
    markTweet(tweetId, i) {
      const idIndex = this.tweetActionIds.indexOf(tweetId)
      this.tweets[i].isSelected = !this.tweets[i].isSelected
      if (this.tweetActionIds.includes(tweetId)) {
        this.tweetActionIds.splice(idIndex, 1)
      } else {
        this.tweetActionIds.push(tweetId)
      }
    },
    markReply(replyId) {
      const idIndex = this.tweetActionIds.indexOf(replyId)
      if (this.tweetActionIds.includes(replyId)) {
        this.tweetActionIds.splice(idIndex, 1)
      } else {
        this.tweetActionIds.push(replyId)
      }
    },
  },
}
</script>

我尝试在数据中添加 replySelected ,然后当在 markReply 中触发单击时,我将 replySelected 更改为 true,但是随后选择了推文的每个回复,这不是我想要的。

P粉029327711P粉029327711242 天前483

全部回复(2)我来回复

  • P粉024986150

    P粉0249861502024-04-01 15:42:07

    您可以在 Nikola 的答案的基础上构建,只需检查它是否在 tweetActionIds 数组中,即可绕过向每条推文添加 isSelected 的额外步骤,然后执行相同的操作并通过回复保持干净

    {{ tweet.tweet_text }}

    {{ reply.tweet_text }}

    {{tweetActionIds}}
    const app = Vue.createApp({
      data() {
        return {
          tweets: []
          tweetActionIds: [],
          categories: [],
        }
      },
      methods: {
        markTweet(tweetId, i) {
          const idIndex = this.tweetActionIds.indexOf(tweetId)
          if (this.tweetActionIds.includes(tweetId)) {
            this.tweetActionIds.splice(idIndex, 1)
          } else {
            this.tweetActionIds.push(tweetId)
          }
        },
        markReply(replyId) {
          const idIndex = this.tweetActionIds.indexOf(replyId)
          if (this.tweetActionIds.includes(replyId)) {
            this.tweetActionIds.splice(idIndex, 1)
          } else {
            this.tweetActionIds.push(replyId)
          }
        },
        isSelected(tweet) {
          return this.tweetActionIds.includes(tweet.tweet_id);
        }
      },
    })

    回复
    0
  • P粉245003607

    P粉2450036072024-04-01 10:49:56

    如果我理解正确,请尝试以下代码片段:

    const app = Vue.createApp({
      data() {
        return {
          tweets: [{id: 1, tweet_id: 1, isSelected: true, tweet_text: 'aaa', tweetReplies: [{tweet_id: 11, tweet_text: 'bbb'}, {tweet_id: 12, tweet_text: 'ccc'}]}, {id: 2, tweet_id: 2, isSelected: false, tweet_text: 'ddd', tweetReplies: [{tweet_id: 21, tweet_text: 'eee'}, {tweet_id: 22, tweet_text: 'fff'}]}],
          tweetActionIds: [],
        }
      },
      methods: {
        markTweet(tweetId, i) {
          const idIndex = this.tweetActionIds.indexOf(tweetId)
          this.tweets[i].isSelected = !this.tweets[i].isSelected
          if (this.tweetActionIds.includes(tweetId)) {
            this.tweetActionIds.splice(idIndex, 1)
          } else {
            this.tweetActionIds.push(tweetId)
          }
        },
        markReply(replyId) {
          const idIndex = this.tweetActionIds.indexOf(replyId)
          if (this.tweetActionIds.includes(replyId)) {
            this.tweetActionIds.splice(idIndex, 1)
          } else {
            this.tweetActionIds.push(replyId)
          }
        },
        checkReply(r) {
          return this.tweetActionIds.includes(r) ? true : false
        }
      },
    })
    
    app.mount('#demo')
    .selected {color: red;}
    sssccc
    

    {{ tweet.tweet_text }}

    {{ reply.tweet_text }}

    {{tweetActionIds}}

    回复
    0
  • 取消回复