首页 > 解决方案 > 如何使用 Vue.js 更新表格数据

问题描述

我有这个管理电子应用程序 DOM 的 vue.js 实例。我需要更新应用程序 UI,应用程序现在正在做一些计算,然后显示结果。保存按钮将指示应用程序保存输入信息和计算结果。我遇到的问题是 DOM 更新。点击保存按钮后,我需要显示数据的表格将刷新以显示新添加的行并将数据显示到图表中。对于我还没有实现的图表,我需要有关如何格式化数据集的帮助,对于其余的,表格暂时不会刷新。

我正在使用 Dexie.js,并且我将 chart.js 作为项目的依赖项。

<!DOCTYPE html>
<html lang="it">
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <!-- https://electronjs.org/docs/tutorial/security#csp-meta-tag -->
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval';" />

    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
    <script>
      window.jQuery = window.$ = require('jquery');
    </script>
    <!-- <script src="node_modules/jquery/dist/jquery.js"></script> -->
    <script src="node_modules/popper.js/dist/umd/popper.js"></script>
    <script src="node_modules/bootstrap/dist/js/bootstrap.js"></script>
    <script src="node_modules/vue/dist/vue.js"></script>

  </head>
  <body>
    <div class="container mb-4 mt-4" id="app">
      <div class="row">

        <div class="col-6 p-3">
          <form>
            <div class="form-row">
              <div class="col-7">
                <label>Data:</label>
                <p>{{ date }}</p>
                <small></small>
              </div>
              <div class="col-6">
                <label>Saldo iniziale:</label>
                <input type="" class="form-control" name="" v-model="start_balance" />
                <small></small>
              </div>
              <div class="col-6">
                <label>Saldo chiusura:</label>
                <input type="" class="form-control" name="" v-model="end_balance" />
                <small></small>
              </div>
              <div class="col-12">
                <a class="btn btn-link fint-weight-bold text-black p-0 mt-4" v-on:click="saveTradingHistory()">Salva</a>
                <small></small>
              </div>
            </div>
          </form>
        </div>

        <div class="col-6 p-3">
          <label>Profitto Giornata:</label>
            <p v-bind:class="{'text-success': positive, 'text-danger': negative }">{{ total }}</p>
          <label>Profitto Totale: </label>
          <p class="text-warning">{{ totalBalance }}</p>
        </div>

        <div class="col-12 p-3">
          <table class="table table-sm table-bordered table-hover">
            <thead>
              <tr>
                <th scope="col">Data</th>
                <th scope="col">Saldo iniziale</th>
                <th scope="col">Saldo chiusura</th>
                <th scope="col">Differenza</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="data in history">
                <th scope="row">{{ data.date }}</th>
                <td>{{ data.start_balance }}</td>
                <td>{{ data.end_balance }}</td>
                <td>{{ data.difference }}</td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="col-12 p-3">
          <canvas id="tradingChart" width="400" height="400"></canvas>
        </div>

      </div>
    </div>

    <script>
      const Electron = require('electron');
      const Dexie = require('dexie');
      const Chart = require('chart.js');

      // var ctx = document.getElementById('tradingChart');
      // let tradingChart = new Chart(ctx, {
      //   type: 'line',
      //
      // });
      let db = new Dexie('trading_balance');

      db.version(1).stores({
        trading_history: "++id,date,start_balance,end_balance,difference"
      });

      let app = new Vue({
        el: '#app',
        data: {
          date: new Date().toLocaleDateString('it-IT'),
            start_balance: null,
            end_balance: null,
          positive: null,
          negative:  null,
          result: 0,
          history: [],
          balance: null
        },
        created: function(){
          this.viewTradingHistory();
        },
        computed: {
                total: function(){
                    this.result = parseFloat(this.end_balance) - parseFloat(this.start_balance);
                if( this.result < 0 ){
                  this.negative = true;
                  this.positive = false;
                }
                if( this.result > 0 ){
                  this.negative = false;
                  this.positive = true;
                }
                return this.result;
                },
            totalBalance: function(){
              return parseFloat(this.balance);
            }
            },
          methods: {
            saveTradingHistory: function(){
              db.trading_history.add({
                date: this.date,
                start_balance: this.start_balance,
                end_balance: this.end_balance,
                difference: this.result
              }).then( (primKey) => {
                // console.log(primKey);
                // console.log(db.trading_history.get(primKey));
              });
            },
            viewTradingHistory: function(){
              db.trading_history.each( (item) =>{
                this.balance += item.difference;
                this.history.push({...item});
              });
              //console.log(this.history);
            },
          }
        });
    </script>
  </body>
</html>

标签: vue.jselectron

解决方案


要在 Vue 中使值或对象具有响应性,它需要正确初始化,通常是作为 a propdata属性或computed值。

Vue 没有看到db变量的变化,因为它没有被初始化为其中之一。

对于表数据数组,您可以像这样初始化它:

data () {
    return {
      items : [
   ['23/03/2020', 2309.99, 2332.25],
   ['24/03/2020', 2343,30, 2424.62],
   ['25/03/2020', 2424.62, 2519.56]
     ],
    }
  },

要编辑数据以在模板中显示,我们可以使用计算属性,该属性将在任何时间this.items更改时更新:

computed: {
   tableData () {
       return this.items.map(x=>{
         x.push((x[2]-x[1]).toFixed(2)) //adds difference column
         return x
       })
   },
  }

现在我们可以items使用方法进行编辑,它的一切都会更新:

methods: {
    addRow () {
      lastRow = this.items.slice(-1)[0]
        this.items.push(
          [lastRow[0] ,lastRow[2], lastRow[2] + 10]
        )
    }
  },

这是该表的一个工作示例:https ://jsfiddle.net/ellisdod/fjqsbtv1/

图表参考我之前的回答


推荐阅读