[英]Toggle class(or change style) of element when element in clicked, 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中有組件。 您可以看到回復以 tweetReplies 的形式存儲在每條推文中的 tweets 數組中。 在 markReply func 中,我成功地將 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,但是隨后選擇了推文的每個回復,這不是我想要的。
如果我理解正確,請嘗試以下代碼段:
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;}
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script> <div id="demo"> <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" :class="{selected: checkReply(reply.tweet_id)}"> <p>{{ reply.tweet_text }}</p> </div> </div> </div> </div> </div> </div> </div> {{tweetActionIds}} </div>
您可以通過繞過將isSelected
添加到每個單獨的 Tweet 的額外步驟來構建 Nikola 的答案,只需檢查它是否在tweetActionIds
數組中,然后對回復執行相同操作以保持干凈
<div id="demo">
<div class="container-full">
<div class="tweets-container">
<div
v-for="(tweet, i) in tweets"
:key="tweet.id"
>
<div
class="tweet-card"
:class="{ selected: isActive(tweet) }"
@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="{ selected: isActive(reply) }"
class="tweet-card tweet-reply"
>
<div class="text">
<p>{{ reply.tweet_text }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{tweetActionIds}}
</div>
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);
}
},
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.