{{ tweet.tweet_text }}
The way I get the data is a bit complicated. I have "tweets" array in which I store data, each tweet is a card, when the card is clicked I successfully change the style (markTweet function), but each tweet also has replies, which are displayed the same as the tweets ( Each reply has its own reply card). The way I get the data from the server:
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 }
Then I have components in vue. You can see that the replies are stored in the tweets array for each tweet, as tweetReplies. In the markReply function I successfully add the id to the array.
<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>
I tried adding replySelected
to the data, then when the click is triggered in markReply I change replySelected
to true, but then every reply to the tweet is selected , this is not what I want.
P粉0249861502024-04-01 15:42:07
You can build on Nikola's answer and just check if it's in the tweetActionIds
array, bypassing the extra step of adding isSelected
to each tweet , then do the same and keep it clean by replying
{{tweetActionIds}}{{ tweet.tweet_text }}
{{ reply.tweet_text }}
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); } }, })
P粉2450036072024-04-01 10:49:56
If I understand correctly, try the following code snippet:
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{{tweetActionIds}}{{ tweet.tweet_text }}
{{ reply.tweet_text }}