Vue смотреть, не замечая изменений в опоре компонента - PullRequest
0 голосов
/ 05 мая 2020

У меня есть калькулятор базового c хранилища, и я передаю некоторые из этих вычисленных значений в свою диаграмму. js компонент в нем props. Моя проблема в том, что когда значение изменяется внутри опоры, наблюдатель этого не замечает. Почему это происходит?

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>

1 Ответ

1 голос
/ 05 мая 2020

Пожалуйста, проверьте этот - Vue не может обнаружить изменения в массиве, если вы используете его как

this.withDocCostTotals[years - 1] = value;

, вы должны использовать Vue.set:

Vue.set(this.withDocCostTotals, years - 1, value);
...