【问题标题】:items.sort not found when trying to get data from db and populate vuetify data table尝试从 db 获取数据并填充 vuetify 数据表时找不到 items.sort
【发布时间】: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。这是正确的方法吗?任何帮助和建议将不胜感激!

【问题讨论】:

    标签: javascript laravel vue.js vuex vuetify.js


    【解决方案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 })
          })
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-31
        • 2015-02-18
        • 2022-01-01
        • 2021-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多