[Vuejs]-How to update v-data-table data in real time?

-5👍

I took the liberty of setting up the project structure with vue-cli and also added mock data and a text-field, let me know if you have any doubts, I’m pretty sure you’ll get the point, clone the public repo, run

 npm install

and then

npm run serve

https://github.com/sdpotts93/vue-simple-table

0👍

So basically what happens in your code is you load your vue into #app, this get rendered and your new #app element looks different – but still get linked to your new vue and rendered – but this time vue somehow fails.

long story short – put your render element into a static template that you can rerender:

i made a simple example from your sketch:

Vue.config.productionTip = false;
const mockData = Array.from({length: 100}, (_, i) => [{
      DATA_IMPRESSAO: `mock${i}`,
      PERIODO: `mock${i}`,
      DESCRICAO: `mock${i}`,
      ID: `mock${i}`,
  }])
  
  let nonReactiveIndex = Math.floor(Math.random()*mockData.length)
 setInterval(() =>
new Vue({
  template: "#example",
  vuetify: new Vuetify(),
  mounted() {
    nonReactiveIndex = Math.floor(Math.random()*mockData.length)
    console.log("mounted", nonReactiveIndex);
    
  },
  data() {
    return {
      headers: [
        { text: "ID", value: "ID", align: "center", width: "10%" },
        { text: "Descrição", value: "DESCRICAO", align: "left", width: "60%" },
        { text: "Período", value: "PERIODO", align: "left", width: "20%" },
        {
          text: "Data Impressão",
          value: "DATA_IMPRESSAO",
          align: "left",
          width: "10%"
        }
      ],
      eventos: mockData[nonReactiveIndex]
      
    };
  },
  
}
).$mount('#app'), 2000)
<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@latest/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>

    <div id="app" class="table-eventos">
      
    </div>
    
    <template id="example">
    <v-app>
        <v-data-table
          :headers="headers"
          :items="eventos"
          :rows-per-page-items="[100]"
          item-key="name"
          class="elevation-1"
        >
          <!-- :pagination.sync="pagination" -->
          <template slot="items" slot-scope="props">
            <tr @click="rowClick(props.item.ID)">
              <td class="text-xs-left">{{ props.item.ID }}</td>
              <td class="text-xs-left">{{ props.item.DESCRICAO }}</td>
              <td class="text-xs-left">{{ props.item.PERIODO }}</td>
              <td class="text-xs-left">{{ props.item.DATA_IMPRESSAO }}</td>
            </tr>
          </template>
        </v-data-table>
      </v-app>
    </template>

It is a better design to implement everything into the vue component and let vue handle reactivity:

Vue.config.productionTip = false;
const mockData = Array.from({length: 100}, (_, i) => [{
      DATA_IMPRESSAO: `mock${i}`,
      PERIODO: `mock${i}`,
      DESCRICAO: `mock${i}`,
      ID: `mock${i}`,
  }])
  

new Vue({
  template: "#example",
  vuetify: new Vuetify(),
  mounted() {
    
    console.log("mounted", this.reactiveIndex);
    
  },
  data() {
    return {
      reactiveIndex : Math.floor(Math.random()*mockData.length),
      headers: [
        { text: "ID", value: "ID", align: "center", width: "10%" },
        { text: "Descrição", value: "DESCRICAO", align: "left", width: "60%" },
        { text: "Período", value: "PERIODO", align: "left", width: "20%" },
        {
          text: "Data Impressão",
          value: "DATA_IMPRESSAO",
          align: "left",
          width: "10%"
        }
      ],
     
      
    };
  },
  computed: {
      eventos(){ return mockData[this.reactiveIndex] }
  },
  methods: {
    load(){
      this.reactiveIndex = Math.floor(Math.random()*mockData.length)
      console.log(this.reactiveIndex)
    }
  }
}
).$mount('#app')
<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@latest/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>

    <div id="app" class="table-eventos">
      
    </div>
    
    <template id="example">
    <v-app>
        <v-btn @click="load">load</v-btn>
        
        <v-data-table
          :headers="headers"
          :items="eventos"
          :rows-per-page-items="[100]"
          item-key="name"
          class="elevation-1"
        >
          <!-- :pagination.sync="pagination" -->
          <template slot="items" slot-scope="props">
            <tr @click="rowClick(props.item.ID)">
              <td class="text-xs-left">{{ props.item.ID }}</td>
              <td class="text-xs-left">{{ props.item.DESCRICAO }}</td>
              <td class="text-xs-left">{{ props.item.PERIODO }}</td>
              <td class="text-xs-left">{{ props.item.DATA_IMPRESSAO }}</td>
            </tr>
          </template>
        </v-data-table>
      </v-app>
    </template>

Leave a comment