【vue篇】Vue 过滤器(Filters)完全指南:优雅处理数据展示

在开发中,你是否经常遇到这样的需求?

"后端返回的时间是 2025-09-19 10:30:00,但我想在页面上显示为'3天前'。"
"价格是 99.9,但需要显示为 ¥99.90。"

传统做法是:

js 复制代码
// ❌ 在 computed 或 methods 中处理
computed: {
  formattedPrice() {
    return '¥' + this.price.toFixed(2);
  }
}

但这样会让组件逻辑变得臃肿。

Vue 过滤器(Filters) 正是为这类场景而生的解决方案。


一、什么是过滤器?

✅ 定义

过滤器(Filter) 是一个纯函数 ,用于格式化 数据的展示,不改变原始数据,只改变用户看到的输出。

📌 核心特点

特性 说明
不修改数据 原始数据保持不变
专注展示层 只影响模板中的显示
可链式调用 多个过滤器串联使用
声明式语法 使用操作符

二、过滤器 vs computed vs methods

对比项 filters computed methods
是否修改数据 ❌ 否 ✅ 可能 ✅ 可能
是否缓存 ❌ 否 ✅ 是 ❌ 否
使用场景 格式化显示 数据计算 事件处理
调用方式 `{{ value filter }}` {{ computedValue }}

📌 示例对比

js 复制代码
data() {
  return {
    price: 99.9,
    date: '2025-09-16 10:30:00'
  };
}

方案 1:使用 filters(推荐)

html 复制代码
<p>价格:{{ price | currency }}</p>
<p>时间:{{ date | timeAgo }}</p>
js 复制代码
filters: {
  currency(price) {
    return price ? `¥${price.toFixed(2)}` : '--';
  },
  timeAgo(dateStr) {
    const date = new Date(dateStr);
    const diff = (Date.now() - date) / 1000;
    if (diff < 60) return '刚刚';
    if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`;
    if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`;
    return `${Math.floor(diff / 86400)}天前`;
  }
}

方案 2:使用 computed

js 复制代码
computed: {
  displayPrice() {
    return this.price ? `¥${this.price.toFixed(2)}` : '--';
  },
  displayTime() {
    // 同上 timeAgo 逻辑
  }
}
html 复制代码
<p>价格:{{ displayPrice }}</p>
<p>时间:{{ displayTime }}</p>

❌ 问题:每个需要格式化的字段都要定义一个 computed,代码重复。


三、如何实现一个过滤器?

✅ 1. 局部过滤器(组件内)

js 复制代码
export default {
  data() {
    return {
      price: 99.9,
      text: 'hello world'
    };
  },
  filters: {
    // 价格格式化
    currency(value) {
      return value != null ? `¥${value.toFixed(2)}` : '--';
    },
    // 首字母大写
    capitalize(value) {
      if (!value) return '';
      return value.toString().charAt(0).toUpperCase() + value.slice(1);
    },
    // 截取字符串
    truncate(value, length = 10) {
      if (!value) return '';
      return value.length > length ? value.slice(0, length) + '...' : value;
    }
  }
}
html 复制代码
<template>
  <div>
    <p>价格:{{ price | currency }}</p>
    <p>标题:{{ text | capitalize }}</p>
    <p>摘要:{{ text | truncate(5) }}</p>
  </div>
</template>

✅ 2. 全局过滤器(推荐复用)

js 复制代码
// filters.js
export const currency = (value) => {
  return value != null ? `¥${value.toFixed(2)}` : '--';
};

export const timeAgo = (dateStr) => {
  // 同上逻辑
};

// main.js
import Vue from 'vue';
import * as filters from './filters';

// 注册所有过滤器
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key]);
});
html 复制代码
<!-- 任何组件中均可使用 -->
<p>{{ price | currency }}</p>
<p>{{ date | timeAgo }}</p>

四、过滤器的高级用法

✅ 1. 链式调用

html 复制代码
<p>{{ text | capitalize | truncate(10) }}</p>
<!-- 先大写,再截取 -->

✅ 2. 接收多个参数

js 复制代码
filters: {
  slice(value, start, end) {
    return value.slice(start, end);
  }
}
html 复制代码
<p>{{ 'Hello World' | slice(0, 5) }}</p>
<!-- 输出:Hello -->

✅ 3. 在 v-bind 中使用(Vue 2.1.0+)

html 复制代码
<div v-bind:id="rawId | formatId"></div>
js 复制代码
filters: {
  formatId(id) {
    return 'user-' + id;
  }
}

五、Vue 3 中的过滤器

⚠️ 重要更新Vue 3 已移除过滤器语法

❌ Vue 3 不再支持

html 复制代码
<!-- Vue 3 中无效 -->
<p>{{ price | currency }}</p>

✅ 替代方案

方案 1:使用 methods

js 复制代码
methods: {
  currency(price) {
    return price ? `¥${price.toFixed(2)}` : '--';
  }
}
html 复制代码
<p>{{ currency(price) }}</p>

方案 2:使用 computed(适合复杂逻辑)

方案 3:使用组合式函数(推荐)

js 复制代码
// composables/useFilters.js
export function useFilters() {
  const currency = (value) => {
    return value != null ? `¥${value.toFixed(2)}` : '--';
  };

  const timeAgo = (dateStr) => {
    // ...
  };

  return { currency, timeAgo };
}
js 复制代码
// 组件中
import { useFilters } from '@/composables/useFilters';

export default {
  setup() {
    const { currency, timeAgo } = useFilters();
    return { currency, timeAgo };
  }
}
html 复制代码
<p>{{ currency(price) }}</p>

六、最佳实践

✅ 推荐使用场景

场景 示例
货币格式化 ¥99.90, $100.00
日期格式化 2025-09-19, 3天前
文本处理 大写、截取、转义
单位添加 km, kg,

❌ 不推荐使用场景

场景 原因
复杂计算 应使用 computed
异步操作 过滤器必须是同步的
数据转换(影响逻辑) 应在 computedmethods 中处理

💡 结语

"过滤器是展示层的'化妆师',只负责美,不负责变。"

  • 优点:语法简洁、逻辑分离、易于复用;
  • ⚠️ 缺点:Vue 3 已移除,需迁移;
  • 💡 建议:在 Vue 2 项目中合理使用;Vue 3 项目使用组合式函数替代。

掌握过滤器,让你的代码更清晰,展示更优雅。

相关推荐
晚霞的不甘几秒前
Flutter for OpenHarmony构建全功能视差侧滑菜单系统:从动效设计到多页面导航的完整实践
前端·学习·flutter·microsoft·前端框架·交互
黎子越几秒前
python相关练习
java·前端·python
A_nanda16 分钟前
c# 用VUE+elmentPlus生成简单管理系统
javascript·vue.js·c#
北极糊的狐37 分钟前
若依项目vue前端启动键入npm run dev 报错:不是内部或外部命令,也不是可运行的程序或批处理文件。
前端·javascript·vue.js
XRJ040618xrj39 分钟前
Nginx下构建PC站点
服务器·前端·nginx
We་ct1 小时前
LeetCode 289. 生命游戏:题解+优化,从基础到原地最优
前端·算法·leetcode·矩阵·typescript
jiayong231 小时前
Vue2 与 Vue3 核心原理对比 - 面试宝典
vue.js·面试·职场和发展
有诺千金1 小时前
VUE3入门很简单(4)---组件通信(props)
前端·javascript·vue.js
2501_944711431 小时前
Vue-路由懒加载与组件懒加载
前端·javascript·vue.js
雨季6662 小时前
Flutter 三端应用实战:OpenHarmony “心流之泉”——在碎片洪流中,为你筑一眼专注的清泉
开发语言·前端·flutter·交互