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

VueJS2渲染报错:TypeError: _vm._f(...) is not a function 求助

解决Vue渲染错误「TypeError: _vm._f(...) is not a function」及页面空白问题

你遇到的这个错误和页面空白问题,核心是Vue 2.x已移除双向过滤器支持,再加上代码里还有几处逻辑疏漏,咱们一步步来修复:

1. 替换双向过滤器,改用单向过滤器+事件处理实现货币格式化

Vue 2.x不再支持read/write形式的双向过滤器,这就是_vm._f(...) is not a function错误的直接诱因。咱们把过滤器改成单向的,同时针对输入框的格式化需求单独处理:

修改过滤器定义

// 替换原双向过滤器,改为单向过滤器
Vue.filter('currencyDisplay', function(val) {
  if (val === null || val === undefined || isNaN(val)) return "$0.00";
  return accounting.formatMoney(val, "$", 2, ".", ",");
});

处理价格输入框的格式化逻辑

给price输入框添加失焦事件,在用户输入完成后统一格式化显示:

<input 
  class="form-control text-right" 
  v-model="row.price" 
  number 
  @blur="formatPrice(row)"
/>

在组件methods中添加格式化方法:

methods: {
  // ... 原有方法
  formatPrice(row) {
    if (row.price) {
      // 先解析输入值为数字,再格式化
      const num = accounting.unformat(row.price);
      row.price = accounting.formatMoney(num, "$", 2, ".", ",");
    }
  },
  // ... 原有方法
}

2. 修复计算属性的逻辑错误

你的total和taxtotal计算属性里引用了不存在的e.total、e.tax_amount属性,应该直接基于row的现有属性计算:

computed: {
  total: function () {
    let t = 0;
    this.rows.forEach(row => {
      const price = accounting.unformat(row.price);
      t += row.qty * price;
    });
    return t;
  },
  taxtotal: function () {
    let tt = 0;
    this.rows.forEach(row => {
      const price = accounting.unformat(row.price);
      tt += row.qty * price * row.tax / 100;
    });
    return tt;
  },
  grandtotal: function () {
    // 将grandtotal改为计算属性,禁止在模板中直接赋值
    const delivery = this.delivery || 0;
    return this.total + this.taxtotal + delivery;
  }
}

同时修改模板中的grandtotal渲染:

<tr>
  <td colspan="5" class="text-right"><strong>GRANDTOTAL</strong></td>
  <td colspan="1" class="text-right"><strong>{{ grandtotal | currencyDisplay }}</strong></td>
  <td></td>
</tr>

3. 补全Sortable指令的依赖

你的自定义v-sortable指令直接使用了Sortable.create,但未引入依赖库:

  • 先安装Sortable.js:
npm install sortablejs --save
  • 在组件中引入:
import Sortable from 'sortablejs';

4. 修复v-for的key值问题

原模板中用row.qty作为key,容易出现重复导致渲染异常,改用index作为临时key:

<tr v-for="(row, index) in rows" v-bind:key="index">

5. 优化添加行的默认值

添加空行时设置默认值,避免计算时出现NaN:

addRow: function (index) {
  try {
    this.rows.splice(index + 1, 0, {
      qty: 1,
      description: "",
      price: 0,
      tax: 0
    });
  } catch(e) {
    console.log(e);
  }
}

完成以上修改后,你应该不会再看到渲染错误,页面能正常加载,同时表格行的排序、增删,以及货币格式化功能都能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:17:07