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
相关产品推荐
相关产品推荐

