如何有条件地更改Vue中td的文本颜色
How to change text color of td in Vue conditionally
我正在使用 json 文件中的数据,如下所示:
{"USD": {"7d": 32053.72, "30d": 33194.68, "24h": 31370.42}, "AUD": {"7d": 43134.11, "30d": 44219.00, "24h": 42701.11}, "RUB": {"7d": 2451451.45, "30d": 2465896.74, "24h": 2398589.80}, "JPY": {"7d": 3537735.55, "30d": 3664620.47, "24h": 3472632.46}, "BRL": {"7d": 167555.18, "30d": 169473.27, "24h": 163054.93}, "ILS": {"7d": 108658.72, "30d": 111663.67, "24h": 106988.58}, "GBP": {"7d": 23257.66, "30d": 23838.55, "24h": 22923.17}, "PLN": {"7d": 124869.61, "30d": 127872.57, "24h": 122668.16}, "CAD": {"7d": 40425.62, "30d": 41444.76, "24h": 39827.13}, "EUR": {"7d": 27187.74, "30d": 27955.81, "24h": 26659.79}}
我在 table 中显示它。我计算 7 天和 30 天的百分比变化,以及该百分比变化是负数还是正数。如果变化是负面的,我想把文本涂成红色,如果是正面的,我想把它涂成绿色,这就是我检查变化是正面还是负面的方式:
// Checking whether the change is positive or negative
if(item['7d'] > item['30d']) {
this.isPositive = true
} else if (item['7d'] < item['30d']) {
this.isNegative = true
}
到目前为止,我使用三元运算符的逻辑不起作用,而且我的 td 文本没有变成红色或绿色。为什么以及如何实现这一目标?这是我的全部代码:
<template>
<div>
<v-data-table
:headers="headers"
:items="bitcoinInfo"
:hide-default-footer="true"
class="primary"
>
<template #item.thirtyDaysDiff="{ item }">
<td :class="isPositive ? 'positive' : 'negative' ? isNegative : 'negative'">{{ calculateThirtyDayDifference(item) }}%</td>
</template>
<template #item.sevenDaysDifference="{ item }">
<td :class="isPositive ? 'positive' : 'negative' ? isNegative : 'negative'">{{ calculateThirtyDayDifference(item) }}%</td>
</template>
</v-data-table>
</div>
</template>
<script>
import axios from 'axios';
export default {
data () {
return {
bitcoinInfo: [],
isNegative: false,
isPositive: false,
headers: [
{
text: 'Currency',
align: 'start',
value: 'currency',
},
{ text: '30 Days Ago', value: '30d' },
{ text: '30 Day Diff %', value: 'thirtyDaysDiff'},
{ text: '7 Days Ago', value: '7d' },
{ text: '7 Day Diff %', value: 'sevenDaysDifference' },
{ text: '24 Hours Ago', value: '24h' },
],
}
},
methods: {
getBitcoinData() {
axios
.get('data.json')
.then((response => {
var convertedCollection = Object.keys(response.data).map(key => {
return {currency: key, thirtyDaysDiff: 0, sevenDaysDifference: 0, ...response.data[key]}
})
this.bitcoinInfo = convertedCollection
}))
.catch(err => console.log(err))
},
calculateThirtyDayDifference(item) {
let calculatedPercent = 100 * Math.abs((item['7d'] - item['30d']) / ((item['7d'] + item['30d']) / 2));
// Checking whether the change is positive or negative
if(item['7d'] > item['30d']) {
this.isPositive = true
} else if (item['7d'] < item['30d']) {
this.isNegative = true
}
return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
},
calculateSevenDayDifference(item) {
let calculatedPercent = 100 * Math.abs((item['24h'] - item['7d']) / ((item['24h'] + item['7d']) / 2));
return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
}
},
mounted() {
this.getBitcoinData()
}
}
</script>
<style>
.negative {
color: red;
}
.positive {
color: green;
}
</style>
你的代码有很多错误我什至不知道从哪里开始...
您使用 Conditional (ternary) operator 的方式有误。它有一个形式 condition ? expression_for_true : expression_for_false
方法calculateThirtyDayDifference
在模板中使用,同时改变了一些数据(isNegative
和isPositive
)。 永远不要那样做!这会导致无限渲染循环。
在大多数情况下,您不需要从模板中调用任何 method
- 由于模板会多次呈现,因此效率非常低。如果您有一些数据并且需要导出更多数据(计算一些东西),更好的解决方案是使用 computed
并提前准备好您需要的所有数据
v-data-table
(docs) 的项目插槽已经呈现 <td>
因此您的代码将在 td
内呈现 td
- 例如使用 span
而不是
const data = JSON.parse('{"USD": {"7d": 32053.72, "30d": 33194.68, "24h": 31370.42}, "AUD": {"7d": 43134.11, "30d": 44219.00, "24h": 42701.11}, "RUB": {"7d": 2451451.45, "30d": 2465896.74, "24h": 2398589.80}, "JPY": {"7d": 3537735.55, "30d": 3664620.47, "24h": 3472632.46}, "BRL": {"7d": 167555.18, "30d": 169473.27, "24h": 163054.93}, "ILS": {"7d": 108658.72, "30d": 111663.67, "24h": 106988.58}, "GBP": {"7d": 23257.66, "30d": 23838.55, "24h": 22923.17}, "PLN": {"7d": 124869.61, "30d": 127872.57, "24h": 122668.16}, "CAD": {"7d": 40425.62, "30d": 41444.76, "24h": 39827.13}, "EUR": {"7d": 27187.74, "30d": 27955.81, "24h": 26659.79}}')
new Vue({
el: '#app',
vuetify: new Vuetify(),
template: `
<v-app>
<v-main>
<v-container>
<v-data-table :headers="headers" :items="rowsToDisplay" :hide-default-footer="true" class="elevation-1">
<template #item.thirtyDaysDiff="{ item }">
<span :class="item.thirtyDaysDiffClass">{{ item.thirtyDaysDiff }}%</span>
</template>
<template #item.sevenDaysDiff="{ item }">
<span :class="item.sevenDaysDiffClass">{{ item.sevenDaysDiff }}%</span>
</template>
</v-data-table>
</v-container>
</v-main>
</v-app>
`,
data() {
return {
bitcoinInfo: data,
headers: [{
text: 'Currency',
align: 'start',
value: 'currency',
},
{
text: '30 Days Ago',
value: '30d'
},
{
text: '30 Day Diff %',
value: 'thirtyDaysDiff'
},
{
text: '7 Days Ago',
value: '7d'
},
{
text: '7 Day Diff %',
value: 'sevenDaysDiff'
},
{
text: '24 Hours Ago',
value: '24h'
},
],
}
},
methods: {
calculateDifference(a, b) {
let calculatedPercent = 100 * Math.abs((a - b) / ((a + b) / 2));
return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
},
getDiffClass(a, b) {
return a > b ? 'positive' : a < b ? 'negative' : ''
}
},
computed: {
rowsToDisplay() {
return Object.keys(this.bitcoinInfo)
.map(key => {
return {
currency: key,
...data[key]
}
}).map((item) => ({
...item,
thirtyDaysDiff: this.calculateDifference(item['7d'], item['30d']),
thirtyDaysDiffClass: this.getDiffClass(item['7d'], item['30d']),
sevenDaysDiff: this.calculateDifference(item['24h'], item['7d']),
sevenDaysDiffClass: this.getDiffClass(item['24h'], item['7d']),
}))
}
}
})
.negative {
color: red;
}
.positive {
color: green;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<div id="app">
</div>
我正在使用 json 文件中的数据,如下所示:
{"USD": {"7d": 32053.72, "30d": 33194.68, "24h": 31370.42}, "AUD": {"7d": 43134.11, "30d": 44219.00, "24h": 42701.11}, "RUB": {"7d": 2451451.45, "30d": 2465896.74, "24h": 2398589.80}, "JPY": {"7d": 3537735.55, "30d": 3664620.47, "24h": 3472632.46}, "BRL": {"7d": 167555.18, "30d": 169473.27, "24h": 163054.93}, "ILS": {"7d": 108658.72, "30d": 111663.67, "24h": 106988.58}, "GBP": {"7d": 23257.66, "30d": 23838.55, "24h": 22923.17}, "PLN": {"7d": 124869.61, "30d": 127872.57, "24h": 122668.16}, "CAD": {"7d": 40425.62, "30d": 41444.76, "24h": 39827.13}, "EUR": {"7d": 27187.74, "30d": 27955.81, "24h": 26659.79}}
我在 table 中显示它。我计算 7 天和 30 天的百分比变化,以及该百分比变化是负数还是正数。如果变化是负面的,我想把文本涂成红色,如果是正面的,我想把它涂成绿色,这就是我检查变化是正面还是负面的方式:
// Checking whether the change is positive or negative
if(item['7d'] > item['30d']) {
this.isPositive = true
} else if (item['7d'] < item['30d']) {
this.isNegative = true
}
到目前为止,我使用三元运算符的逻辑不起作用,而且我的 td 文本没有变成红色或绿色。为什么以及如何实现这一目标?这是我的全部代码:
<template>
<div>
<v-data-table
:headers="headers"
:items="bitcoinInfo"
:hide-default-footer="true"
class="primary"
>
<template #item.thirtyDaysDiff="{ item }">
<td :class="isPositive ? 'positive' : 'negative' ? isNegative : 'negative'">{{ calculateThirtyDayDifference(item) }}%</td>
</template>
<template #item.sevenDaysDifference="{ item }">
<td :class="isPositive ? 'positive' : 'negative' ? isNegative : 'negative'">{{ calculateThirtyDayDifference(item) }}%</td>
</template>
</v-data-table>
</div>
</template>
<script>
import axios from 'axios';
export default {
data () {
return {
bitcoinInfo: [],
isNegative: false,
isPositive: false,
headers: [
{
text: 'Currency',
align: 'start',
value: 'currency',
},
{ text: '30 Days Ago', value: '30d' },
{ text: '30 Day Diff %', value: 'thirtyDaysDiff'},
{ text: '7 Days Ago', value: '7d' },
{ text: '7 Day Diff %', value: 'sevenDaysDifference' },
{ text: '24 Hours Ago', value: '24h' },
],
}
},
methods: {
getBitcoinData() {
axios
.get('data.json')
.then((response => {
var convertedCollection = Object.keys(response.data).map(key => {
return {currency: key, thirtyDaysDiff: 0, sevenDaysDifference: 0, ...response.data[key]}
})
this.bitcoinInfo = convertedCollection
}))
.catch(err => console.log(err))
},
calculateThirtyDayDifference(item) {
let calculatedPercent = 100 * Math.abs((item['7d'] - item['30d']) / ((item['7d'] + item['30d']) / 2));
// Checking whether the change is positive or negative
if(item['7d'] > item['30d']) {
this.isPositive = true
} else if (item['7d'] < item['30d']) {
this.isNegative = true
}
return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
},
calculateSevenDayDifference(item) {
let calculatedPercent = 100 * Math.abs((item['24h'] - item['7d']) / ((item['24h'] + item['7d']) / 2));
return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
}
},
mounted() {
this.getBitcoinData()
}
}
</script>
<style>
.negative {
color: red;
}
.positive {
color: green;
}
</style>
你的代码有很多错误我什至不知道从哪里开始...
您使用 Conditional (ternary) operator 的方式有误。它有一个形式
condition ? expression_for_true : expression_for_false
方法
calculateThirtyDayDifference
在模板中使用,同时改变了一些数据(isNegative
和isPositive
)。 永远不要那样做!这会导致无限渲染循环。
在大多数情况下,您不需要从模板中调用任何 method
- 由于模板会多次呈现,因此效率非常低。如果您有一些数据并且需要导出更多数据(计算一些东西),更好的解决方案是使用 computed
并提前准备好您需要的所有数据
v-data-table
(docs) 的项目插槽已经呈现<td>
因此您的代码将在td
内呈现td
- 例如使用span
而不是
const data = JSON.parse('{"USD": {"7d": 32053.72, "30d": 33194.68, "24h": 31370.42}, "AUD": {"7d": 43134.11, "30d": 44219.00, "24h": 42701.11}, "RUB": {"7d": 2451451.45, "30d": 2465896.74, "24h": 2398589.80}, "JPY": {"7d": 3537735.55, "30d": 3664620.47, "24h": 3472632.46}, "BRL": {"7d": 167555.18, "30d": 169473.27, "24h": 163054.93}, "ILS": {"7d": 108658.72, "30d": 111663.67, "24h": 106988.58}, "GBP": {"7d": 23257.66, "30d": 23838.55, "24h": 22923.17}, "PLN": {"7d": 124869.61, "30d": 127872.57, "24h": 122668.16}, "CAD": {"7d": 40425.62, "30d": 41444.76, "24h": 39827.13}, "EUR": {"7d": 27187.74, "30d": 27955.81, "24h": 26659.79}}')
new Vue({
el: '#app',
vuetify: new Vuetify(),
template: `
<v-app>
<v-main>
<v-container>
<v-data-table :headers="headers" :items="rowsToDisplay" :hide-default-footer="true" class="elevation-1">
<template #item.thirtyDaysDiff="{ item }">
<span :class="item.thirtyDaysDiffClass">{{ item.thirtyDaysDiff }}%</span>
</template>
<template #item.sevenDaysDiff="{ item }">
<span :class="item.sevenDaysDiffClass">{{ item.sevenDaysDiff }}%</span>
</template>
</v-data-table>
</v-container>
</v-main>
</v-app>
`,
data() {
return {
bitcoinInfo: data,
headers: [{
text: 'Currency',
align: 'start',
value: 'currency',
},
{
text: '30 Days Ago',
value: '30d'
},
{
text: '30 Day Diff %',
value: 'thirtyDaysDiff'
},
{
text: '7 Days Ago',
value: '7d'
},
{
text: '7 Day Diff %',
value: 'sevenDaysDiff'
},
{
text: '24 Hours Ago',
value: '24h'
},
],
}
},
methods: {
calculateDifference(a, b) {
let calculatedPercent = 100 * Math.abs((a - b) / ((a + b) / 2));
return Math.max(Math.round(calculatedPercent * 10) / 10, 2.8).toFixed(2);
},
getDiffClass(a, b) {
return a > b ? 'positive' : a < b ? 'negative' : ''
}
},
computed: {
rowsToDisplay() {
return Object.keys(this.bitcoinInfo)
.map(key => {
return {
currency: key,
...data[key]
}
}).map((item) => ({
...item,
thirtyDaysDiff: this.calculateDifference(item['7d'], item['30d']),
thirtyDaysDiffClass: this.getDiffClass(item['7d'], item['30d']),
sevenDaysDiff: this.calculateDifference(item['24h'], item['7d']),
sevenDaysDiffClass: this.getDiffClass(item['24h'], item['7d']),
}))
}
}
})
.negative {
color: red;
}
.positive {
color: green;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<div id="app">
</div>