如何实时更新v-data-table数据?

时间:2019-07-23 18:56:15

标签: javascript vue.js vuetify.js

我正在开发节点和电子应用程序。我正在使用vuetify生成从Oracle数据库加载数据的表(v-data-table)。 数据根据输入的值而变化,但是该表不会更新!

当输入值更改时: process.env.ANO_SEM = input.val()

然后我调用 loadData()函数

process.env.ANO_SEM 用作 getEventos()函数

中sql查询的参数

我的代码:


 $('#input').keyup(e => {
        if (e.keyCode == 13) {
            process.env.ANO_SEM = $('#input').val()
            loadData()
        }
 })

// Get data from BD
async function getEventos() {
    const sql = await fs
        .readFileSync(path.join(process.env.ROOT_PATH, 'src/db/sql/get-evento.sql'))
        .toString()
    return await db.getData(sql, [process.env.ANO_SEM])
}

async function loadData() {
    let data = await getEventos()
    console.log(data) // the data aways change, but the table never update
    new Vue({
        el: '#app',
        methods: {
            rowClick(idEvento) {
                require(path.join(process.env.CTRL_PATH, './evento/evento-ctrl.js'))(
                    window.$,
                    idEvento
                )
            }
        },
        data: function() {
            return {
                selectedItem: 'Sample',
                pagination: {
                    sortBy: 'ID'
                },
                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: data
            }
        }
    })
}

我的html:

<div id="app" class="table-eventos">
        <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>
    </div>

2 个答案:

答案 0 :(得分:0)

因此,基本上,代码中发生的事情是将vue加载到#app中,这会呈现,并且新的#app元素看起来有所不同-但仍链接到新的vue并呈现-但这次vue某种程度上失败了。< / p>

长话短说-将您的render元素放入可以重新渲染的静态模板中:

我从您的草图中举了一个简单的例子:

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>


将所有内容实施到vue组件中并让vue处理反应性是一个更好的设计:

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>

答案 1 :(得分:-2)

我随意使用vue-cli设置项目结构,还添加了模拟数据和文本字段,如果您有任何疑问,请告诉我,我很确定您会明白的,克隆公共仓库运行

 npm install

然后

npm run serve

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