You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue2.5.2+Vuex3.0.1+Vuetify1.0.16:v-data-table单元测试不渲染问题

基于Vuex + Vuetify的分页数据表格实现方案

针对你正在开发的Vue项目(技术栈:Vue 2.5.2、Vuex 3.0.1、Vuetify 1.0.16),我整理了完整的组件实现思路和代码示例,核心是用v-data-table渲染Vuex Store中的数据并实现分页功能,同时搭配编辑表单:

组件完整代码示例

<template>
  <v-container>
    <!-- 店铺名称编辑输入框 -->
    <v-text-field 
      id="shopName" 
      label="店铺名称"
      v-model="editedItem.name" 
      required
      placeholder="请输入店铺名称"
    ></v-text-field>

    <!-- 保存按钮 -->
    <v-btn 
      id="save" 
      color="blue darken-1" 
      flat 
      @click.native="handleSave"
      :disabled="!editedItem.name.trim()"
    >保存</v-btn>

    <!-- 带分页的数据表格 -->
    <v-data-table 
      :headers="tableHeaders" 
      :pagination.sync="pagination" 
      :items="shops" 
      class="elevation-1 mt-4"
    >
      <!-- 自定义表格行内容 -->
      <template slot="items" slot-scope="props">
        <td>{{ props.item.name }}</td>
        <td>
          <v-btn icon small @click="handleEdit(props.item)">
            <v-icon>edit</v-icon>
          </v-btn>
          <v-btn icon small color="error" @click="handleDelete(props.item.id)">
            <v-icon>delete</v-icon>
          </v-btn>
        </td>
      </template>

      <!-- 空数据提示 -->
      <template slot="no-data">
        <v-alert :value="true" color="info" icon="info">
          暂无店铺数据,请添加新店铺
        </v-alert>
      </template>
    </v-data-table>
  </v-container>
</template>

<script>
import { mapState, mapActions, mapMutations } from 'vuex'

export default {
  name: 'ShopTable',
  data() {
    return {
      // 编辑项局部状态
      editedItem: { id: null, name: '' },
      // 分页配置(与表格双向同步)
      pagination: {
        sortBy: 'name',
        descending: false,
        page: 1,
        rowsPerPage: 10,
        totalItems: 0
      },
      // 表格表头配置
      tableHeaders: [
        { text: '店铺名称', value: 'name', sortable: true },
        { text: '操作', value: 'actions', sortable: false, align: 'right' }
      ]
    }
  },
  computed: {
    // 从Vuex映射店铺列表数据
    ...mapState({
      shops: state => state.shops.list,
      totalShops: state => state.shops.total
    })
  },
  watch: {
    // 监听总条数变化,更新分页配置
    totalShops(newVal) {
      this.pagination.totalItems = newVal
    }
  },
  methods: {
    // 映射Vuex的actions
    ...mapActions(['saveShop', 'deleteShop', 'fetchShops']),

    // 保存店铺
    async handleSave() {
      try {
        await this.saveShop(this.editedItem)
        // 保存成功后重置表单
        this.editedItem = { id: null, name: '' }
        // 重新拉取数据(如果是后端存储)
        await this.fetchShops(this.pagination)
      } catch (err) {
        console.error('保存失败:', err)
        // 可添加错误提示
        this.$snackbar.open({ text: '保存店铺失败,请重试', color: 'error' })
      }
    },

    // 编辑店铺
    handleEdit(shop) {
      this.editedItem = { ...shop }
    },

    // 删除店铺
    async handleDelete(shopId) {
      if (confirm('确定要删除该店铺吗?')) {
        try {
          await this.deleteShop(shopId)
          // 删除后重新拉取数据
          await this.fetchShops(this.pagination)
        } catch (err) {
          console.error('删除失败:', err)
          this.$snackbar.open({ text: '删除店铺失败,请重试', color: 'error' })
        }
      }
    }
  },
  // 组件挂载时拉取初始数据
  async mounted() {
    await this.fetchShops(this.pagination)
  }
}
</script>

核心实现说明

  • Vuex数据交互:通过mapState获取店铺列表和总条数,用mapActions调用异步操作(保存、删除、拉取数据),确保数据状态集中管理
  • 分页同步:利用:pagination.sync实现组件分页状态与表格的双向绑定,同时监听总条数变化更新分页的totalItems,保证分页逻辑正确
  • 表单处理:编辑项使用组件局部状态,避免污染Vuex全局状态,保存后重置表单并刷新数据
  • 表格自定义:通过插槽自定义行内容和空数据提示,提升用户体验

Vuex Store模块示例(参考)

// store/modules/shops.js
const state = {
  list: [],
  total: 0
}

const mutations = {
  SET_SHOPS(state, { list, total }) {
    state.list = list
    state.total = total
  },
  ADD_OR_UPDATE_SHOP(state, shop) {
    const index = state.list.findIndex(item => item.id === shop.id)
    if (index !== -1) {
      state.list.splice(index, 1, shop)
    } else {
      state.list.push(shop)
    }
  },
  DELETE_SHOP(state, shopId) {
    state.list = state.list.filter(item => item.id !== shopId)
    state.total -= 1
  }
}

const actions = {
  async fetchShops({ commit }, pagination) {
    // 模拟后端请求,实际替换为你的API调用
    const response = await fetch(`/api/shops?page=${pagination.page}&limit=${pagination.rowsPerPage}&sort=${pagination.sortBy}&desc=${pagination.descending}`)
    const { data, total } = await response.json()
    commit('SET_SHOPS', { list: data, total })
  },
  async saveShop({ commit }, shop) {
    const method = shop.id ? 'PUT' : 'POST'
    const url = shop.id ? `/api/shops/${shop.id}` : '/api/shops'
    const response = await fetch(url, {
      method,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(shop)
    })
    const savedShop = await response.json()
    commit('ADD_OR_UPDATE_SHOP', savedShop)
    return savedShop
  },
  async deleteShop({ commit }, shopId) {
    await fetch(`/api/shops/${shopId}`, { method: 'DELETE' })
    commit('DELETE_SHOP', shopId)
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

这样就能完整实现一个基于Vuex管理数据、带分页功能的Vuetify数据表格组件了,完全适配你使用的技术栈版本。

内容的提问来源于stack exchange,提问作者user2850652

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:31:41