使用 Vuetify <v-data-table> 进行服务器端分页和搜索

问题描述

我目前正在制作一个包含电影数据表的 CRUD 应用程序。我使用 themoviedb 作为我的 API 和 VueJS、vuetify、axios 和 vuex。我正在尝试实现服务器端分页搜索,但出现很多错误。到目前为止,这是我所得到的:(我知道这可能是一团糟,但我正在学习)

我的应用组件

<template>
  <v-app>
    <v-main>
      <v-container>
        <v-card style="padding: 70px 60px 70px 70px;
                background-color: black;
                background-size: 1500px 2000px;" 
                >
          <v-card color="blue accent-4" 
                style="padding: 10px;Box-shadow: 1px 3px 62px 0px rgba(255,255,1);"
                class="elevation-3">
            <v-data-table
              :items="movies"
              :headers="headers"
              :options.sync="options"
            >
              <template v-slot:top>
                <v-toolbar flat
                          style="background-color: #504a4a; color: white"
                >
                  <v-toolbar-title>
                      POPULAR MOVIES
                  </v-toolbar-title>
                  <v-text-field
                    v-model="search"
                    append-icon="mdi-magnify"
                    label="search"
                    single-line
                    hide-details
                    style="margin-left: 150px"
                    dark
                  ></v-text-field>
                  <v-divider
                    class="mx-4"
                    inset
                    vertical
                  ></v-divider>
                  <v-spacer></v-spacer>
              <new-movie></new-movie>
            </v-toolbar>
          </template>
              <template v-slot:[`item.actions`]="{ item }">
                <v-btn color="blue accent-4" dark small class="mr-1 mb-2" @click.stop="{
                  detail = { 
                    Title: item.title,Overview: item.overview,Votes: item.Vote_average,Date: item.release_date,Path: item.poster_path
                    }
                  }"
                >
                  Read More
                </v-btn>
                <v-btn color="blue accent-4" dark small class="mr-1 mb-2" @click.stop="{edit = {id: item.id,title: item.title,overview: item.overview,Votes: item.Vote_average}}">Edit</v-btn>
                <v-btn color="blue accent-4" dark small class="mr-1 mb-2" @click.stop="idMovie = item.id">Delete</v-btn>
              </template>      
            </v-data-table>
            <details-movie v-model="detail"
            ></details-movie>
            <edit-movie v-model="edit"></edit-movie>
            <delete-movie v-model="idMovie"></delete-movie>
        </v-card>
      </v-card>  
    </v-container>
    </v-main>
  </v-app>
</template>

<script>
import {mapState} from 'vuex';
import deleteMovie from './components/deleteMovie.vue';
import detailsMovie from './components/detailsMovie.vue';
import editMovie from './components/editMovie.vue';
import newMovie from './components/newMovie.vue';
export default {
  components: { detailsMovie,editMovie,newMovie,deleteMovie },name: 'App',data: function() {
    return {
      detail: null,edit: null,search: '',idMovie: null,options: {},}
  },computed: {
    headers() {
      return [
                {text: "Title",value: "title"},{text: "Overview",value: "overview"},{text: "Votes",value:"Vote_average"},{text: 'Actions',value: 'actions',sortable: false},]
    },...mapState({
            movies:state => state.movies
    }),},watch: {
    options: {
        handler () {
          this.$store.dispatch('getMovies')
        },deep: true,}
    },}

</script>

我在 /store 中的 index.js

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';
import {public_key} from '../movie'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    movies: [],options: {
      page: 0,mutations: {
 
    SET_MOVIES(state,movies) {
      state.movies = movies
      movies.forEach(item => {
        movies.push(item)
        console.log(item)
      });
    },NEW_MOVIE(state,newMovie){
      console.log(newMovie)
      let movies = state.movies.concat(newMovie);
      state.movies = movies
    },DELETE_MOVIE(state,idMovie){
      let movies = state.movies.filter( m => m.id != idMovie)
      state.movies = movies;
    },EDIT_MOVIE(state,editedMovie){
      state.movies.forEach( m => {  
        if(m.id == editedMovie.id) {
          m = editedMovie;
        }
      })
    },SET_PAGINATION(state,options){
      const page = options
    }
      
  },actions: {
  
    async getMovies({commit}){
      let response = await axios.get(`https://api.themoviedb.org/3/movie/popular?api_key=${public_key}&language=en-US`)
      .then((response) => {
        commit('SET_MOVIES',response.data.results)
        commit('SET_PAGINATION',response.data.page)
      });
     },async addMovie({commit},newMovie){
        console.log(newMovie)
       commit('NEW_MOVIE',newMovie)
     },async deleteM({commit},idMovie){
        console.log(idMovie)
        commit('DELETE_MOVIE',idMovie)
   },async editMovie({commit},editedMovie){
        console.log(editedMovie.id)
        commit('EDIT_MOVIE',editedMovie);
      }

   },})

我得到的错误

Uncaught (in promise) ReferenceError: page is not defined
    at Store.SET_PAGINATION (index.js?4360:46)
    at wrappedMutationHandler (vuex.esm.js?2f62:844)
    at commitIterator (vuex.esm.js?2f62:466)
    at Array.forEach (<anonymous>)
    at eval (vuex.esm.js?2f62:465)
    at Store._withCommit (vuex.esm.js?2f62:624)
    at Store.commit (vuex.esm.js?2f62:464)
    at boundCommit (vuex.esm.js?2f62:409)
    at eval (index.js?4360:56)

我真的很感激任何帮助!

解决方法

你承诺了

commit('SET_PAGINATION',response.data.page)

但没有在 page 中使用 SET_PAGINATION,可以改为:

SET_PAGINATION(state,page){
  state.options.page = page 
}