You need to enable JavaScript to run this app. VueJS中VueGoodTable的formatFn如何正确访问data中的unit属性
优惠活动
大模型
产品
解决方案
定价
更多

VueJS中VueGoodTable的formatFn如何正确访问data中的unit属性

问题描述

我现有使用VueGoodTable组件的代码,需要支持用户动态切换金额的单位,原有代码如下:

<template>
  <div class="container">
    <h1>This is the datatable page</h1>
    <div class="unit">
      <!-- 单选框绑定unit,可选值为1、1000、1000000,经vue-devtools确认unit可以正常切换 -->
    </div>
    <vue-good-table :columns="columns" :rows="rows" />
  </div>
</template>

<script>
import "vue-good-table/dist/vue-good-table.css";
import { VueGoodTable } from "vue-good-table";

export default {
  components: {
    VueGoodTable,
  },
  data() {
    return {
      unit: 1000,
      columns: [
        {
          label: "Amount",
          field: "amount",
          type: "number",
          formatFn: function (val) {
            let returnedVal = val / 100;
            // 此处this指向列配置对象,无法访问到Vue实例的unit属性
            returnedVal = returnedVal / this.unit;
            return returnedVal.toFixed(2);
          },
        },
      ],
      rows: [],
    };
  },
  // 其他接口请求逻辑省略
};
</script>

效果示意图
运行后金额计算结果为NaN,排查发现formatFn内的this指向当前列配置对象而非Vue实例,无法正确获取unit属性。


解决方案

根因:定义在列配置中的普通函数formatFn被调用时,执行上下文被绑定到了当前列配置对象,而非Vue组件实例,因此无法通过this访问到unit属性。

方案1:将columns调整为计算属性(最推荐)

将列配置从data移到计算属性中,计算属性的this天然绑定Vue实例,且unit变化时会自动触发列配置更新,表格格式自动同步:

<script>
import "vue-good-table/dist/vue-good-table.css";
import { VueGoodTable } from "vue-good-table";

export default {
  components: {
    VueGoodTable,
  },
  data() {
    return {
      unit: 1000,
      rows: [],
    };
  },
  computed: {
    columns() {
      return [
        {
          label: "金额",
          field: "amount",
          type: "number",
          formatFn: (val) => {
            let returnedVal = val / 100;
            returnedVal = returnedVal / this.unit;
            return returnedVal.toFixed(2);
          },
        },
        // 其余列配置照常添加
      ]
    }
  },
  // 其余业务逻辑保持不变
};
</script>

方案2:利用data函数入参捕获组件实例

data函数执行时会接收当前组件实例作为第一个入参,可提前捕获实例供formatFn使用:

data(vm) {
  return {
    unit: 1000,
    columns: [
      {
        label: "金额",
        field: "amount",
        type: "number",
        formatFn: function (val) {
          let returnedVal = val / 100;
          // 直接使用提前捕获的vm实例访问unit属性
          returnedVal = returnedVal / vm.unit;
          return returnedVal.toFixed(2);
        },
      },
    ],
    rows: [],
  };
}

注意:该方案下unit变更后需要手动触发表格重渲染才会生效,适合单位切换频率低的场景。

方案3:将格式化逻辑抽离到methods

把金额格式化逻辑定义为组件方法,methods中的方法天然绑定Vue实例的this:

export default {
  components: { VueGoodTable },
  data() {
    return {
      unit: 1000,
      rows: []
    }
  },
  computed: {
    columns() {
      return [
        {
          label: "金额",
          field: "amount",
          type: "number",
          formatFn: this.formatAmount
        }
      ]
    }
  },
  methods: {
    formatAmount(val) {
      let returnedVal = val / 100;
      returnedVal = returnedVal / this.unit;
      return returnedVal.toFixed(2);
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 13:21:02