我有一个基本的存储计算器,我把这些计算出来的一些值传递给我的 chart.js 组件的道具。我的问题是,当一个值在道具中改变时,观察者不会注意到它。为什么会发生这种情况?
Vue.component('chart', {
template: '<canvas id="chart"></canvas>',
props: {
totals: Array,
},
watch: {
totals: {
deep: true,
handler() {
console.log('Prop changed');
}
}
},
methods: {
createChart() {
new Chart(document.getElementById("chart"), {
type: 'bar',
data: {
datasets: [{
label: 'Bar Dataset',
data: [10, 20, 30, 40]
}, {
label: 'Line Dataset',
data: [50, 50, 50, 50],
type: 'line'
}],
labels: ['January', 'February', 'March', 'April']
}
});
}
},
mounted() {
this.createChart();
}
});
var app1 = new Vue({
el: '#savings_calculator',
data: {
dataAmount: '42',
growingRate: '35',
currencySymbol: 'GBP',
expertCost: '50000',
managedData: '150',
storageBackupCost: '2000',
obsolescence: '30',
withDocCostTotals: [,,,,],
withoutDocCostTotals: [,,,,],
},
methods: {
storageVolCalcWithoutDoc(years) {
return Math.round(((this.growingRate / 100 + 1)**years)*this.dataAmount);
},
smeCostCalcWithoutDoc(years) {
let value = Math.round((this.dataAmount*((this.growingRate / 100 + 1)**years) / this.managedData)*this.expertCost);
this.withoutDocCostTotals[years - 1] = value;
return this.currencyFormat(value);
},
hardwareBackupCalcWithoutDoc(years) {
let value = Math.round((this.dataAmount*( (this.growingRate / 100 + 1)**years ) )*this.storageBackupCost);
this.withoutDocCostTotals[years - 1] = this.withoutDocCostTotals[years - 1] + value;
return this.currencyFormat(value);
},
storageVolCalcWithDoc(years) {
return Math.round((Math.abs(this.obsolescence / 100 - 1)*this.dataAmount)*((this.growingRate / 100 + 1)**years));
},
smeCostCalcWithDoc(years) {
let value = Math.round(Math.abs(this.obsolescence / 100 - 1)*(this.dataAmount*((this.growingRate / 100 + 1)**years) / this.managedData)*this.expertCost);
this.withDocCostTotals[years - 1] = value;
return this.currencyFormat(value);
},
hardwareBackupCalcWithDoc(years) {
let value = Math.round(Math.abs(this.obsolescence / 100 - 1)*(this.dataAmount*( (this.growingRate / 100 + 1)**years ) )*this.storageBackupCost);
this.withDocCostTotals[years - 1] = this.withDocCostTotals[years - 1] + value;
return this.currencyFormat(value);
},
annualSavings(year) {
let value = this.withoutDocCostTotals[year - 1] - this.withDocCostTotals[year - 1];
return this.currencyFormat(value);
},
cumulativeSavings(year) {
let value = 0;
for(let i = 0; i < year; i++) {
value = value + this.withoutDocCostTotals[i] - this.withDocCostTotals[i];
}
return this.currencyFormat(value);
},
currencyFormat(value) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: this.currencySymbol,
maximumFractionDigits: 0,
minimumFractionDigits: 0,
}).format(value);
}
}
});
label{
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="savings_calculator">
<div class="input container">
<label>
<span>How many Terabytes of unstructured data do you have?</span>
<input type="number" v-model="dataAmount">
</label>
<label>
<span>This is growing a what rate a year?</span>
<input type="number" v-model="growingRate">%
</label>
<label>
<span>This analysis will be carried out in</span>
<select id="currency" v-model="currencySymbol">
<option value="GBP">Gbp</option>
<option value="USD">Usd</option>
</select>
</label>
<label>
<span>Annual cost per head for storage experts</span>
<span v-if="currencySymbol == 'GBP'">£</span>
<span v-else>$</span>
<input type="number" v-model="expertCost">
<!-- prepend currency symbol: number with commas -->
</label>
<label>
<span>One storage expert is required to manage how much data?</span>
<input type="number" v-model="managedData">
</label>
<label>
<span>Storage and backup costs per TB (p.a)</span>
<input type="number" v-model="storageBackupCost">
</label>
<label>
<span>Obsolescence target</span>
<input type="number" v-model="obsolescence">%
</label>
</div>
<div class="output container">
<div class="details">
<table>
<tr>
<th></th>
<th>Year</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
</tr>
<tr>
<th></th>
<th>Storage Volume</th>
<td>{{ storageVolCalcWithoutDoc(1) }}TB</td>
<td>{{ storageVolCalcWithoutDoc(2) }}TB</td>
<td>{{ storageVolCalcWithoutDoc(3) }}TB</td>
<td>{{ storageVolCalcWithoutDoc(4) }}TB</td>
<td>{{ storageVolCalcWithoutDoc(5) }}TB</td>
</tr>
<tr>
<th>Without Doc</th>
<th>Costs for storage SME</th>
<td>{{ smeCostCalcWithoutDoc(1) }}</td>
<td>{{ smeCostCalcWithoutDoc(2) }}</td>
<td>{{ smeCostCalcWithoutDoc(3) }}</td>
<td>{{ smeCostCalcWithoutDoc(4) }}</td>
<td>{{ smeCostCalcWithoutDoc(5) }}</td>
</tr>
<tr>
<th></th>
<th>Hardware and backup costs</th>
<td>{{ hardwareBackupCalcWithoutDoc(1) }}</td>
<td>{{ hardwareBackupCalcWithoutDoc(2) }}</td>
<td>{{ hardwareBackupCalcWithoutDoc(3) }}</td>
<td>{{ hardwareBackupCalcWithoutDoc(4) }}</td>
<td>{{ hardwareBackupCalcWithoutDoc(5) }}</td>
</tr>
</table>
<table>
<tr>
<th></th>
<th>Year</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
</tr>
<tr>
<th></th>
<th>Storage Volume</th>
<td>{{ storageVolCalcWithDoc(1) }}TB</td>
<td>{{ storageVolCalcWithDoc(2) }}TB</td>
<td>{{ storageVolCalcWithDoc(3) }}TB</td>
<td>{{ storageVolCalcWithDoc(4) }}TB</td>
<td>{{ storageVolCalcWithDoc(5) }}TB</td>
</tr>
<tr>
<th>With Doc</th>
<th>Costs for storage SME</th>
<td>{{ smeCostCalcWithDoc(1) }}</td>
<td>{{ smeCostCalcWithDoc(2) }}</td>
<td>{{ smeCostCalcWithDoc(3) }}</td>
<td>{{ smeCostCalcWithDoc(4) }}</td>
<td>{{ smeCostCalcWithDoc(5) }}</td>
</tr>
<tr>
<th></th>
<th>Hardware and backup costs</th>
<td>{{ hardwareBackupCalcWithDoc(1) }}</td>
<td>{{ hardwareBackupCalcWithDoc(2) }}</td>
<td>{{ hardwareBackupCalcWithDoc(3) }}</td>
<td>{{ hardwareBackupCalcWithDoc(4) }}</td>
<td>{{ hardwareBackupCalcWithDoc(5) }}</td>
</tr>
</table>
<table>
<tr>
<th></th>
<th>Year 1</th>
<th>Year 2</th>
<th>Year 3</th>
<th>Year 4</th>
<th>Year 5</th>
</tr>
<tr>
<th>obsolescence savings (annual)</th>
<td>{{ annualSavings(1) }}</td>
<td>{{ annualSavings(2) }}</td>
<td>{{ annualSavings(3) }}</td>
<td>{{ annualSavings(4) }}</td>
<td>{{ annualSavings(5) }}</td>
</tr>
<tr>
<th>obsolescence savings (cumulative)</th>
<td>{{ cumulativeSavings(1) }}</td>
<td>{{ cumulativeSavings(2) }}</td>
<td>{{ cumulativeSavings(3) }}</td>
<td>{{ cumulativeSavings(4) }}</td>
<td>{{ cumulativeSavings(5) }}</td>
</tr>
</table>
</div>
<chart v-if="withDocCostTotals.length" v-bind:totals="withDocCostTotals" />
</div>
</div>
请检查 这个 - 如果你使用像这样的数组,Vue无法检测到它的变化。
this.withDocCostTotals[years - 1] = value;
你应该使用 Vue.set
:
Vue.set(this.withDocCostTotals, years - 1, value);