【问题标题】:Vuejs compute property doesn't get updated properlyVuejs 计算属性没有正确更新
【发布时间】:2020-05-22 06:07:04
【问题描述】:

我是 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”始终显示为零。

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

【问题讨论】:

  • 您确定要更改值吗? windows.recordCount = 0 没有反应。
  • 我将值设置在 window.recordCount = response.data.total; Q1:用“windows”代替“window”有什么区别吗? Q2:假设不是reactive,那么如何通过api调用设置recordCount值?
  • 我根据@DimaVak 评论对我的问题进行了一些更改。
  • 是否有理由在窗口上设置 recordCount 而不是将其作为 vue 数据中的属性?
  • 我首先尝试将其作为数据中的属性,但是当我这样做时,我无法通过 getRows 方法访问相同的属性。我试图访问 this.recordCount 之类的属性,但它没有用。谢谢!

标签: vue.js computed-properties ag-grid-vue


【解决方案1】:

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

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

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

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

请注意,我将 serverSideDatasource 放在了一个小的开头,因为在命名变量和函数时,camelCase 被广泛认为是最佳实践。

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

recordCount: 0

现在您的所有数据和方法(函数)都在 Vue 中,您可以使用“this”来访问它们。 所以替换“窗口”。有了这个。”您使用它的所有地方。

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

注意:在 data 和 computed 中都有一个名为 recordCount 的属性会发生冲突,所以即使你保留它,你也必须重命名 computed。

请告诉我这是否能解决问题,或者它能让你走多远:)

【讨论】:

  • 嗨,Thomas,我更喜欢你的方法,但我很难正确执行它。当我在 vue 实例中移动 serverSideDataSource() 时,在 v-on 处理程序中出现错误:“ReferenceError: serverSideDatasource is not defined” 我指的是ag-grid.com/javascript-grid-server-side-model-pagination
  • 我想通了。我需要调用“this.serverSideDatasource()”而不是“new serverSideDatasource()”。让我试试,让你知道结果,谢谢!
  • 正要问这个:)
  • 我尝试了你的建议。即在 vue 实例中移动 serverSideDatasource,删除计算属性,并将其作为数据属性传递,然后最终将变量分配为 this.recordCount = response.data.total;。不幸的是,该值仍然是0。我不知道我是否遗漏了什么。
  • 可能是页面大小下拉菜单在 getRows 触发之前被初始化。有什么建议可以解决这个问题吗?
猜你喜欢
  • 2019-07-14
  • 2018-12-11
  • 2018-09-27
  • 2020-08-21
  • 2019-12-05
  • 2018-08-28
  • 2020-09-09
  • 1970-01-01
  • 2018-11-12
相关资源
最近更新 更多