尝试从 db 获取数据并填充 vuetify 数据表时找不到 items.sort

Posted

技术标签:

【中文标题】尝试从 db 获取数据并填充 vuetify 数据表时找不到 items.sort【英文标题】:items.sort not found when trying to get data from db and populate vuetify data table 【发布时间】:2019-07-15 15:54:06 【问题描述】:

我正在尝试从数据库中获取数据并使用 laravel、vue 和 vuetify 填充 vuetify 表。示例到目前为止,我已经设法获取数据表头,但是当我运行 npm run dev 时,它可以正常编译而没有任何错误,但是在控制台中我得到了这个

未捕获的类型错误:items.sort 不是函数 在 app.js:60601

我已经在控制台中打印了 axios 函数的响应,我用它来从数据库中获取数据

Promise
__proto__: Promise
 [[PromiseStatus]]: "resolved"
 [[PromiseValue]]: Array(2)
  0: Day: "MONDAY", RouteCode: "MO-A", RouteName: "TORRINGTON/RAJAGIRIYA", 
     VehicleNo: "LZ-7878", DriverID: "Janaka Amarathunga", …
  1: Day: "MONDAY", RouteCode: "MO-C", RouteName: " AHUNGALLA / KALUTHARA", 
     VehicleNo: null, DriverID: null, …
 length: 2
 __proto__: Array(0)

app.js 文件

require('./bootstrap');
window.Vue = require('vue');
window.Vuetify = require('vuetify');
import Vuex from 'vuex'
import store from './store/store'
import 'vuetify/dist/vuetify.min.css'

Vue.use(Vuetify,Vuex);

Vue.component('example-component', require('./components/ExampleComponent.vue').default);

Vue.component('daily-delivery-planner', require('./components/DailyDeliveryPlanner.vue').default);

const app = new Vue(
    el: '#app',
    store,
);

store.js 文件

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

export default new Vuex.Store(
    strict: true, 
    state: 
      pagination: 
        descending: true,
        page: 1,
        rowsPerPage: 4,
        sortBy: 'fat',
        totalItems: 0,
        rowsPerPageItems: [1, 2, 4, 8, 16]
      ,
      items: []
    ,
    mutations: 
      setPagination (state, payload) 
        state.pagination = payload
      ,
      _setItems (state,  items, totalItems ) 
        state.items = items
        Vue.set(state.pagination, 'totalItems', totalItems)
      
    ,
    actions: 
      queryItems (context) 

        return new Promise((resolve, reject) => 

          const  sortBy, descending, page, rowsPerPage  = context.state.pagination

          setTimeout(() => 

            let dd = getData()
            console.log(dd);

            let items = dd
            const totalItems = items.length

            if (sortBy) 
              items = items.sort((a, b) => 
                const sortA = a[sortBy]
                const sortB = b[sortBy]

                if (descending) 
                  if (sortA < sortB) return 1
                  if (sortA > sortB) return -1
                  return 0
                 else 
                  if (sortA < sortB) return -1
                  if (sortA > sortB) return 1
                  return 0
                
              )
            

            if (rowsPerPage > 0) 
              items = items.slice((page - 1) * rowsPerPage, page * rowsPerPage)
            

            context.commit('_setItems',  items, totalItems )

            resolve()
          , 1000)
        )
      
    ,
    getters: 
      loading (state) 
        return state.loading
      ,
      pagination (state) 
        return state.pagination
      ,
      items (state) 
        return state.items
      
    
  )

  async function getData() 
    try 
        const response = await axios.get('getDayRelatedData/'+'Monday');
        return response.data;
     catch (error) 
        console.error(error);
    


DailyDeliveryPlanner.vue

<template>
<v-app>
<div class="page-content browse container-fluid">
  <div class="row">
      <div class="col-md-12">
          <div class="panel panel-bordered">
              <div class="panel-body">
                <div class="col-md-9">
                  <div class="form-group row">
                      <label for="day" class="col-sm-1 col-form-label custom-label">Select A Day</label>
                      <div class="col-sm-9">
                        <v-btn color="info" id="Monday">Monday</v-btn>
                        <v-btn color="info" id="Tuesday">Tuesday</v-btn>
                        <v-btn color="info" id="Wednesday">Wednesday</v-btn>
                        <v-btn color="info" id="Thursday">Thursday</v-btn>
                        <v-btn color="info" id="Friday">Friday</v-btn>
                        <v-btn color="info" id="Saturday">Saturday</v-btn>
                        <v-btn color="info" id="Sunday">Sunday</v-btn>
                      </div>
                  </div>
                </div>
                <div class="col-md-3">
                  <div class="">
                      <h4>Route Plan Code : <span class="label label-info" id="routeplanno"> routeplan_no </span></h4>
                  </div>
                </div>
              </div>
          </div>
        </div>
        <div class="col-md-12">
            <div class="panel panel-bordered">
                <div class="panel-body">
                    <div class="col-md-12">
                        <v-data-table
                            must-sort
                            :headers="headers"
                            :pagination.sync="pagination"
                            :rows-per-page-items="pagination.rowsPerPageItems"
                            :total-items="pagination.totalItems"
                            :loading="loading"
                            :items="items"
                            class="elevation-1"
                        >
                            <template slot="items" slot-scope="props">
                                <td class='text-xs-right'> props.item.Day </td>
                                <td class='text-xs-right'> props.item.RouteCode </td>
                                <td class='text-xs-right'> props.item.RouteName </td>
                                <td class='text-xs-right'> props.item.VehicleNo </td>
                                <td class='text-xs-right'> props.item.DriverID </td>
                                <td class='text-xs-right'> props.item.Routercode1 </td>
                                <td class='text-xs-right'> props.item.Routercode2 </td>
                                <td class='text-xs-right'> props.item.Capacity </td>
                                <td class='text-xs-right'> props.item.planned_trips_count </td>
                                <td class='text-xs-right'> props.item.Trip_Count </td>
                                <td class='text-xs-right'> props.item.Location </td>
                                <td class='text-xs-right'> props.item.FG_Count </td>
                                <td class='text-xs-right'> props.item.PET_Count </td>
                                <td class='text-xs-right'> props.item.Createuser </td>
                            </template>
                        </v-data-table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</v-app>
</template>

<script>

export default 
    data () 
    return 
      loading: false,
      routeplan_no:"",
      headers: [
            
            text: 'Day',
            align: 'left',
            sortable: false,
            value: 'day'
            ,
             text: 'Route Code', value: 'route_code' ,
             text: 'Route Name', value: 'route_name' ,
             text: 'Vehicle No', value: 'vehicle_no' ,
             text: 'Driver Name', value: 'driver_name' ,
             text: 'Router 01', value: 'router_01' ,
             text: 'Router 02', value: 'router_02' ,
             text: 'Capacity', value: 'capacity' ,
             text: 'Planned Trip Count', value: 'planned_trip_count' ,
             text: 'Trip Count', value: 'trip_count' ,
             text: 'Location', value: 'location' ,
             text: 'FG Count', value: 'fg_count' ,
             text: 'PET Count', value: 'pet_count' ,
             text: 'Created User', value: 'created_user' ,
        ]
    
  ,
  watch: 
    pagination: 
      handler () 
        this.loading = true
        this.$store.dispatch('queryItems')
          .then(result => 
            this.loading = false
          )
      ,
      deep: true
    
  ,
  computed: 
    pagination: 
      get: function () 
        return this.$store.getters.pagination
      ,
      set: function (value) 
        this.$store.commit('setPagination', value)
      
    ,
    items () 
      return this.$store.getters.items
    
  ,
  methods: 
      getUserData: function() 
                axios.get('retreiveUserData')
                    .then((data) => 
                        if(data.alert=='success')
                            this.routeplan_no = data.data;
                        else
                            this.routeplan_no = Math.floor(1000 + Math.random() * 9000);
                        
                    );
            
  ,
  beforeMount() 
            this.getUserData();
        



</script>

由于我是 vue 的初学者,我一直关注 this codepen。这是正确的方法吗?任何帮助和建议将不胜感激!

【问题讨论】:

【参考方案1】:

为什么会这样:

您从同步函数内部调用了异步getData(它在promise 内部并不重要)。异步链坏了。

由于 javascript 异步运行,您的 items.sort(可能)发生在之前异步 getData 已解决,因此,items 仍然是 undefined 并且在尝试 items.sort 时您得到了类型错误。

如何解决:

异步进程应该在函数链的下游一直保持异步。 您正在调用getData,它是异步的,因此,queryItems 也应该是异步的,因此它能够等待响应。我看到你正在混合 Promise 和 asyncawait,所以我把一个转换后的 queryItems(它返回一个 Promise)带到了一个以 bot 方式的异步函数:

使用async-await:

async queryItems (context) 
return new Promise((resolve, reject) => 

  const  sortBy, descending, page, rowsPerPage  = context.state.pagination

  setTimeout(async () => 
  try
    let dd = await getData()
   catch
    return reject();
    console.log(dd);

    let items = dd
    const totalItems = items.length

    if (sortBy) 
      items = items.sort((a, b) => 
        ................................
     return resolve();

只使用承诺语法:

queryItems (context) 

return new Promise((resolve, reject) => 

  const  sortBy, descending, page, rowsPerPage  = context.state.pagination

  setTimeout(() => 
  return getData().then(dd=>
    console.log(dd);

    let items = dd;
    const totalItems = items.length
    if (sortBy) 
      items = items.sort((a, b) => 
        ................................
         return resolve();
      ).catch(e=>
            return reject(e))

【讨论】:

【参考方案2】:

您的 getData 函数返回一个 Promise。不能直接排序。您应该使用async/await 代替.then() 等待Promise 结果

actions: 
  queryItems (context) 
    return getData().then(dd => 
      const  sortBy, descending, page, rowsPerPage  = context.state.pagination
      let items = dd
      const totalItems = items.length

      if (sortBy) 
        items = items.sort((a, b) => 
          const sortA = a[sortBy]
          const sortB = b[sortBy]

          if (descending) 
            if (sortA < sortB) return 1
            if (sortA > sortB) return -1
            return 0
           else 
            if (sortA < sortB) return -1
            if (sortA > sortB) return 1
            return 0
          
        )
      

      if (rowsPerPage > 0) 
        items = items.slice((page - 1) * rowsPerPage, page * rowsPerPage)
      

      context.commit('_setItems',  items, totalItems )
    )
  

【讨论】:

以上是关于尝试从 db 获取数据并填充 vuetify 数据表时找不到 items.sort的主要内容,如果未能解决你的问题,请参考以下文章

Vuetify 容器不会填充高度

使用 Jest 对 Vuetify 数据表进行单元测试

从 DB 获取数据以在下拉 HTML/CSS/MYSQL/PHP 中设置为默认值

Axios 数据未显示在 Vuetify 表中

如何在 Vuetify 数据表中连接外部数据

HTML5 Web SQL DB - 最大表大小?