Reputation: 185
I'm currently trying to change the color of some cells on my table in a vue project. I read about class and style binding on the docs and on some other resources online but I couldn't get what I want working.
I have a table that is filled with data from firestore and based on the data I want to change the colors of some cells. The first cell is the one where it is displaying the person "rank", I want to give the .gold-star
class if the person has a rank of "Gold Star", .silver-star
if "Silver Star" and .bronze-star
if "Bronze Star".
The second cell would be the one that shows the person total points, this cell will be based on a bunch of conditions based on the person ranks and their total points, for example if person rank is "Bronze Star" and the person has >50
points, I want do add the class .change-rank
to the total cell so I know its time to change. Don't know if I made myself clear.
Here is the code so far for my table component (I trimmed it a little bit to make it easier to read).
<template>
<div>
<v-snackbar v-model="snackbar">
<span>Player Added!</span>
<v-btn color="blue" text @click="snackbar = false">Close</v-btn>
</v-snackbar>
<h3 class="font-weight-medium text-center pa-3 ma-3 display-1">Member List</h3>
<template v-if="isMember || isAdmin">
<v-simple-table fixed-header height="70vh">
<template v-slot:default>
<thead>
<tr>
<th class="text-left title">Name</th>
<th class="text-left title">Rank</th>
<th class="text-left title">Total</th>
</tr>
</thead>
<tbody>
<tr v-for="(member, index) in members" :key="index">
<td>
{{member.name}}
</td>
<td>{{member.rank}}</td>
<td>{{member.total}}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</template>
</div>
</template>
<script>
import {
db,
fv,
tstp
} from "../data/firebaseInit";
import firebase from "firebase/app";
import Popup from "../components/Popup";
export default {
components: {
Popup
},
data() {
return {
isAdmin: false,
isMember: false,
snackbar: false,
members: []
};
},
created() {
this.fetchDb();
},
methods: {
fetchDb() {
db.collection("members")
.orderBy("name")
.onSnapshot(snap => {
const members = [];
snap.forEach(doc => {
let newPlayer = doc.data();
newPlayer.id = doc.id;
members.push(newPlayer);
});
this.members = members;
});
}
}
};
</script>
<style scoped>
h3 {
text-decoration: underline;
color: #37474f;
}
.gold-star {
background-color: #ffee58;
}
.silver-star {
background-color: #BDBDBD;
}
.bronze-star {
background-color: #cd7f32;
}
.change-rank {
background-color: #00C853;
}
</style>
Upvotes: 3
Views: 2827
Reputation: 2694
All you need to do is assign a class conditionally to each element in the loop:
<tr
v-for="(member, index) in members"
:key="index"
:class="{
'gold-star': member.rank === 'Gold star',
'silver-star': member.rank === 'Silver star',
'bronze-star': member.rank === 'Bronze star',
}"
>
...
Do the same thing for the points: 'change-rank': member.total > 50
You can also move this code to a method
and make your HTML cleaner:
<tr
v-for="(member, index) in members"
:key="index"
:class="getTableClasses(member)"
>
...
methods: {
getTableClasses(member) {
let color = member.rank.toLowerCase().replace(' ', '-')
let changeRank = member.total > 50 ? 'change-rank' : ''
return `${color} ${changeRank}`
}
}
Upvotes: 3
Reputation: 10262
You can apply your class based on input. Simply create a object that contain class and value like below
const classes = {
'Gold star': 'gold-star',
'Silver star': 'silver-star',
'Bronze star': 'bronze-star'
};
And when you doing looping just passed your rank value in above object so it will return the class name based on rank. like below
<td :class="classe[item.rank]">{{ item.rank }}</td>
You could check here with working Codepen demo.
CODE SNIPPET
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th class="text-left title">Name</th>
<th class="text-left title">Rank</th>
<th class="text-left title">Total</th>
</tr>
</thead>
<tbody>
<tr v-for="(member, index) in members" :key="index">
<td>{{member.name}}</td>
<td :class="classe[item.rank]">{{ item.rank }}</td>
<td>{{member.total}}</td>
</tr>
</tbody>
</template>
</v-simple-table>
Upvotes: 1