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

Vue3中无法用Vuex Getter数据填充ag-grid问题排查

问题描述

尝试使用Vuex Getter返回的异步数据填充ag-grid组件,调试时能看到Getter已有数据,但网格的rowData属性仍为空,同时控制台出现以下警告和错误:

警告信息

runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of mounted hook
at <Anonymous class="ag-theme-alpine" id="myGrid" columnDefs= {value: Array(7)} ... >
at
at <DesignSystem onVnodeUnmounted=fn ref=Ref< Proxy {callWebsocket: ƒ, sendMessage: ƒ, …} > >
at
at
at <ConfigProvider theme-overrides= {common: {…}, Checkbox: {…}, Radio: {…}, Button: {…}, Switch: {…}} theme=null >

错误信息

Uncaught (in promise) TypeError: this.gridOptions.columnDefs.forEach is not a function
at GridOptionsWrapper2.checkColumnDefProperties (ag-grid-community.cjs.js:18300:37)
at GridOptionsWrapper2.init (ag-grid-community.cjs.js:18240:18)
at ag-grid-community.cjs.js:1113:76
at Array.forEach ()
at Context2.callLifeCycleMethodsOnBean (ag-grid-community.cjs.js:1113:24)
at ag-grid-community.cjs.js:1096:70
at Array.forEach ()
at Context2.callLifeCycleMethods (ag-grid-community.cjs.js:1096:23)
at Context2.wireBeans (ag-grid-community.cjs.js:975:14)
at new Context2 (ag-grid-community.cjs.js:953:14)

组件模板

<template>
  <div class="test-container">        
    <ag-grid-vue
      class="ag-theme-alpine"
      id="myGrid"
      :columnDefs="columnDefs"
      domLayout="autoHeight"
      unSortIcon="true"
      @grid-ready="onGridReady"
      :animateRows="true"
      :rowData="rowData"
      :defaultColDef="defaultColDef"
    >
    </ag-grid-vue>
  </div>
</template>

Setup函数(Vue3组合式API)

import { AgGridVue } from "ag-grid-vue3";
import { useActions, useGetters } from "vuex-composition-helpers";
import { reactive, onMounted, ref } from "vue";
export default {
components: {
  AgGridVue,
},
setup() {
  const gridApi = ref(null);
  const onGridReady = (params) => {
    gridApi.value = params.api;
  };
  const rowData = reactive([]);
  const columnDefs = reactive({
    value: [
      { field: "brandId", sortable: true, checkboxSelection: true },
      { field: "category" },
      { field: "channel", headerName: "Brand" },
      { field: "channelReferenceId", headerName: "Requested" },
      { field: "id", headerName: "Updated" },
      { field: "status", headerName: "Subject" },
      { field: "subject", headerName: "Requester" },
    ],
  });
  const defaultColDef = {
    sortable: true,
    filter: true,
    flex: 1,
  };
  const { fetchTickets } = useActions({
    fetchTickets: "tickets/fetchTickets",
  });
  const { tickets } = useGetters({
    tickets: "tickets/getRowData",
  });
  function getTickets() {
    fetchTickets();
  }
  getTickets();
  onMounted(() => {
    rowData.value = tickets.value;
  });
  return {
    onGridReady,
    columnDefs,
    rowData,
    defaultColDef,
    tickets,
    getTickets,
  };
},

使用vuex-composition-helpers从API获取Tickets数据,通过Getter作为数据源填充ag-grid。


解决方案

1. 修复columnDefs类型错误

控制台核心错误columnDefs.forEach is not a function,原因是你把columnDefs定义成了包含value属性的响应式对象,但ag-grid要求columnDefs必须是数组类型。

修改方式:直接将columnDefs定义为响应式数组:

// 替换原columnDefs定义
const columnDefs = reactive([
  { field: "brandId", sortable: true, checkboxSelection: true },
  { field: "category" },
  { field: "channel", headerName: "Brand" },
  { field: "channelReferenceId", headerName: "Requested" },
  { field: "id", headerName: "Updated" },
  { field: "status", headerName: "Subject" },
  { field: "subject", headerName: "Requester" },
]);

模板中保持:columnDefs="columnDefs"即可,无需改动。

2. 修复rowData的赋值与异步数据监听

  • 用reactive([])定义的rowData是数组,不能通过rowData.value赋值(这是ref的用法),需要直接操作数组内容。
  • 异步数据tickets在onMounted时可能还未返回,仅单次赋值无法响应后续数据变化,需要用watch监听tickets的更新,实时同步到rowData。

修改步骤:

  1. 导入watch:
import { reactive, onMounted, ref, watch } from "vue";
  1. 添加监听逻辑,替换原onMounted中的赋值代码:
const rowData = reactive([]);

// 监听tickets变化,实时更新rowData
watch(tickets, (newTickets) => {
  // 清空原数组并添加新数据
  rowData.splice(0, rowData.length, ...newTickets);
}, { immediate: true }); // immediate: true 确保初始化时执行一次

3. 优化数据加载时机(可选)

可以在网格初始化完成后(onGridReady回调中)再触发数据请求,避免网格未就绪就加载数据:

const onGridReady = (params) => {
  gridApi.value = params.api;
  // 网格就绪后请求数据
  getTickets();
};

// 移除原来的getTickets()调用

修改后的完整Setup函数

import { AgGridVue } from "ag-grid-vue3";
import { useActions, useGetters } from "vuex-composition-helpers";
import { reactive, onMounted, ref, watch } from "vue";
export default {
components: {
  AgGridVue,
},
setup() {
  const gridApi = ref(null);
  const onGridReady = (params) => {
    gridApi.value = params.api;
    getTickets();
  };
  const rowData = reactive([]);
  const columnDefs = reactive([
    { field: "brandId", sortable: true, checkboxSelection: true },
    { field: "category" },
    { field: "channel", headerName: "Brand" },
    { field: "channelReferenceId", headerName: "Requested" },
    { field: "id", headerName: "Updated" },
    { field: "status", headerName: "Subject" },
    { field: "subject", headerName: "Requester" },
  ]);
  const defaultColDef = {
    sortable: true,
    filter: true,
    flex: 1,
  };
  const { fetchTickets } = useActions({
    fetchTickets: "tickets/fetchTickets",
  });
  const { tickets } = useGetters({
    tickets: "tickets/getRowData",
  });
  function getTickets() {
    fetchTickets();
  }
  
  watch(tickets, (newTickets) => {
    rowData.splice(0, rowData.length, ...newTickets);
  }, { immediate: true });

  return {
    onGridReady,
    columnDefs,
    rowData,
    defaultColDef,
    tickets,
    getTickets,
  };
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:50:25