Vuejs 计算 属性 未正确更新

Vuejs compute property doesn't get updated properly

我是 Vuejs 的新手,我正在关注他们的文档,这非常有帮助。但是,我发现很难理解计算属性实际上是如何触发的。

我正在为我的项目使用 ag-grid,我想将总行数更新到我的自定义页面大小下拉列表中。

以下是我的代码:

<template>
     <div id="ag-grid-demo">
      <vx-card>
       <!-- TABLE ACTION ROW -->
       <div class="flex flex-wrap justify-between items-center">
        <!-- ITEMS PER PAGE -->
        <div class="mb-4 md:mb-0 mr-4 ag-grid-table-actions-left"></div>

        <!-- TABLE ACTION COL-2: SEARCH & EXPORT AS CSV -->
        <div class="flex flex-wrap items-center justify-between ag-grid-table-actions-right">
          <vs-button class="mb-4 md:mb-0" @click="gridApi.exportDataAsCsv()">Export as CSV</vs-button>
        </div>
      </div>
      <ag-grid-vue
        ref="agGridTable"
        :gridOptions="gridOptions"
        class="ag-theme-material w-100 my-4 ag-grid-table"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :rowModelType="rowModelType"
        @grid-ready="onGridReady"
        rowSelection="multiple"
        colResizeDefault="shift"
        :animateRows="true"
        :pagination="true"
        :paginationPageSize="paginationPageSize"
        :cacheBlockSize="cacheBlockSize"
        :enableRtl="$vs.rtl"
        :modules="modules"
      ></ag-grid-vue>
      <div class="flex flex-wrap justify-between items-center">
        <!-- CUSTOM PAGESIZE DROP-DWON -->
        <div class="mb-4 md:mb-0 mr-4 ag-grid-table-actions-left">
          <vs-dropdown vs-trigger-click class="cursor-pointer">
            <div class="p-4 border border-solid d-theme-border-grey-light rounded-full d-theme-dark-bg cursor-pointer flex items-center justify-between font-medium">
              <span class="mr-2"
              >{{ currentPage * paginationPageSize - (paginationPageSize - 1) }} - {{ recordCount - currentPage * paginationPageSize > 0 ? currentPage * paginationPageSize : recordCount }} of {{ recordCount }}</span>
              <feather-icon icon="ChevronDownIcon" svgClasses="h-4 w-4" />
            </div>
            <vs-dropdown-menu>
              <vs-dropdown-item @click="gridApi.paginationSetPageSize(10)">
                <span>10</span>
              </vs-dropdown-item>
              <vs-dropdown-item @click="gridApi.paginationSetPageSize(50)">
                <span>50</span>
              </vs-dropdown-item>
              <vs-dropdown-item @click="gridApi.paginationSetPageSize(100)">
                <span>100</span>
              </vs-dropdown-item>
              <vs-dropdown-item @click="gridApi.paginationSetPageSize(150)">
                <span>150</span>
              </vs-dropdown-item>
            </vs-dropdown-menu>
          </vs-dropdown>
        </div>

        <!-- CUSTOM TABLE PAGINATION  -->
        <div class="flex flex-wrap items-center justify-between ag-grid-table-actions-right">
          <vs-pagination :total="totalPages" :max="maxPageNumbers" v-model="currentPage" />
        </div>
      </div>
    </vx-card>
    </div>
    </template>


    <script>
import { AgGridVue } from "ag-grid-vue";
import { ServerSideRowModelModule } from "@ag-grid-enterprise/server-side-row-model";
import { MenuModule } from "@ag-grid-enterprise/menu";
import { ColumnsToolPanelModule } from "@ag-grid-enterprise/column-tool-panel";
import CompanyServices from "../../../_services/company.service";

import "@/assets/scss/vuexy/extraComponents/agGridStyleOverride.scss";

export default {
  components: {
    AgGridVue
  },
  data() {
    return {
      gridOptions: {},
      maxPageNumbers: 7,
      gridApi: null,
      defaultColDef: {
        sortable: true,
        editable: false,
        resizable: true,
        suppressMenu: false
      },
      columnDefs: [
        { headerName: "Id", field: "id", filter: false },
        {
          headerName: "Company Name",
          field: "companyName",
          filter: true,
          checkboxSelection: true,
          headerCheckboxSelectionFilteredOnly: true
        }
      ],
      rowModelType: "serverSide",
      modules: [ServerSideRowModelModule, MenuModule, ColumnsToolPanelModule],
      cacheBlockSize: 10,
    };
  },
  computed: {
    paginationPageSize() {
      if (this.gridApi) return this.gridApi.paginationGetPageSize();
      else return 10;
    },
    totalPages() {
      if (this.gridApi) return this.gridApi.paginationGetTotalPages();
      else return 0;
    },
    currentPage: {
      get() {
        if (this.gridApi) return this.gridApi.paginationGetCurrentPage() + 1;
        else return 1;
      },
      set(val) {
        this.gridApi.paginationGoToPage(val - 1);
      }
    },
   recordCount: function() {
      if (window.recordCount === undefined) return 0;
      else return window.recordCount;
   }
  },
  methods: {
    onGridReady: function(params) {
      var datasource = new ServerSideDatasource();
      params.api.setServerSideDatasource(datasource);
    }
  },
  mounted() {
    this.gridApi = this.gridOptions.api;
    this.gridColumnApi = this.gridOptions.columnApi;
  }
};    
window.ServerSideDatasource = function ServerSideDatasource(server) {
  return {
    getRows: function(params) {
      CompanyServices.list({
        startRow: params.request.startRow,
        endRow: params.request.endRow,
        SortColumn: "CompanyName",
        SortOrder: "asc"
      })
        .then(response => {
          window.recordCount = response.data.total;
          params.successCallback(response.data.rows, response.data.total);
        })
        .catch(error => {
          params.failCallback();
        });
    }
  };
};
</script>

我的问题是计算 属性 'recordCount' 不会随着 'window.recordCount' 的更改而更新。 'recordCount' 始终将值显示为零。

有人可以在这里阐明一下吗? 提前致谢!

这里似乎有几个问题,主要是您在 vue 实例之外设置数据和函数。

首先,你不应该在 window 上设置任何数据,Vue 有很多方法来处理你的数据并使它们对你来说都是反应性的。

首先将 window.ServerSideDataSource 函数移动到 vue 实例中。 在 Vue 中,函数放在 "methods" 下,所以在你的 onGridReady 函数之后,添加一个 , 然后输入:

serverSideDatasource() {
  return {
    getRows: functions(params) {..}
  }
}

请注意,我将 serverSideDatasource 以小的 s 开头,因为驼峰命名法被广泛认为是命名变量和函数时的最佳做法。

接下来,您的 window.recordCount 应该放入 Vue 的数据中。只需将其添加到 cacheBlockSize 之后并设置如下:

recordCount: 0

现在您所有的数据和方法(函数)都在 Vue 中,您可以使用 "this" 访问它们。 因此,将 "window." 替换为 "this." 所有你使用它的地方。

现在,由于您的 recordCount 从 0 开始,并且仅在您调用 getRows 时更改,因此不需要计算的 recordCount,因此将其删除。

注意:在 data 和 computed 中同时使用 属性 和 computed 调用 recordCount 会发生冲突,因此即使保留它,您也必须重命名 computed。

请告诉我这是否解决了问题,或者它对您有多大帮助:)