常见过滤器示例

这里收集了常用的过滤器示例,可以直接在项目中使用。常用过滤器示例集合,包括日期、货币、文本等格式化过滤器。

文本处理

大小写转换

Vue.filter('uppercase', function(value) {
  return value ? value.toUpperCase() : ''
})

Vue.filter('lowercase', function(value) {
  return value ? value.toLowerCase() : ''
})

Vue.filter('capitalize', function(value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

使用:

<p>{{ 'hello' | uppercase }}</p>
<p>{{ 'HELLO' | lowercase }}</p>
<p>{{ 'hello' | capitalize }}</p>

文本截断

Vue.filter('truncate', function(value, length = 20, suffix = '...') {
  if (!value) return ''
  value = value.toString()
  return value.length > length ? value.slice(0, length) + suffix : value
})

使用:

<p>{{ longText | truncate(50) }}</p>
<p>{{ longText | truncate(30, '…') }}</p>

去除空格

Vue.filter('trim', function(value) {
  return value ? value.trim() : ''
})

Vue.filter('removeSpaces', function(value) {
  return value ? value.replace(/\s/g, '') : ''
})

首字母缩写

Vue.filter('abbreviate', function(value, length = 2) {
  if (!value) return ''
  const words = value.split(' ')
  return words.slice(0, length).map(w => w.charAt(0).toUpperCase()).join('')
})

使用:

<p>{{ 'John Doe' | abbreviate }}</p>

输出:JD

数字格式化

货币格式

Vue.filter('currency', function(value, symbol = '¥', decimals = 2) {
  value = Number(value)
  if (isNaN(value)) return ''
  return symbol + value.toFixed(decimals)
})

Vue.filter('currencyWithComma', function(value, symbol = '¥') {
  value = Number(value)
  if (isNaN(value)) return ''
  return symbol + value.toLocaleString('zh-CN', { minimumFractionDigits: 2 })
})

使用:

<p>{{ 99.9 | currency }}</p>
<p>{{ 1234567.89 | currencyWithComma }}</p>

输出:

¥99.90
¥1,234,567.89

千分位

Vue.filter('thousands', function(value) {
  value = Number(value)
  if (isNaN(value)) return ''
  return value.toLocaleString()
})

使用:

<p>{{ 1234567 | thousands }}</p>

输出:1,234,567

百分比

Vue.filter('percentage', function(value, decimals = 2) {
  value = Number(value)
  if (isNaN(value)) return ''
  return (value * 100).toFixed(decimals) + '%'
})

使用:

<p>{{ 0.856 | percentage }}</p>

输出:85.60%

文件大小

Vue.filter('fileSize', function(bytes) {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
})

使用:

<p>{{ 1024 | fileSize }}</p>
<p>{{ 1048576 | fileSize }}</p>

输出:

1 KB
1 MB

日期格式化

基础日期格式

Vue.filter('date', function(value, format = 'YYYY-MM-DD') {
  const date = new Date(value)
  if (isNaN(date.getTime())) return ''
  
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')
  
  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds)
})

使用:

<p>{{ timestamp | date }}</p>
<p>{{ timestamp | date('YYYY年MM月DD日') }}</p>
<p>{{ timestamp | date('YYYY-MM-DD HH:mm:ss') }}</p>

相对时间

Vue.filter('relativeTime', function(value) {
  const date = new Date(value)
  if (isNaN(date.getTime())) return ''
  
  const now = new Date()
  const diff = now - date
  const seconds = Math.floor(diff / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)
  const days = Math.floor(hours / 24)
  const months = Math.floor(days / 30)
  const years = Math.floor(days / 365)
  
  if (seconds < 60) return '刚刚'
  if (minutes < 60) return minutes + '分钟前'
  if (hours < 24) return hours + '小时前'
  if (days < 30) return days + '天前'
  if (months < 12) return months + '个月前'
  return years + '年前'
})

使用:

<p>{{ timestamp | relativeTime }}</p>

数组处理

列表显示

Vue.filter('list', function(value, separator = ', ') {
  if (!Array.isArray(value)) return ''
  return value.join(separator)
})

使用:

<p>{{ tags | list }}</p>
<p>{{ tags | list(' | ') }}</p>

数组计数

Vue.filter('count', function(value) {
  if (!Array.isArray(value)) return 0
  return value.length
})

对象处理

JSON 格式化

Vue.filter('json', function(value, indent = 2) {
  return JSON.stringify(value, null, indent)
})

使用:

<pre>{{ user | json }}</pre>

取属性值

Vue.filter('get', function(obj, key) {
  return obj ? obj[key] : ''
})

使用:

<p>{{ user | get('name') }}</p>

布尔值处理

Vue.filter('yesNo', function(value) {
  return value ? '是' : '否'
})

Vue.filter('boolean', function(value, trueText = '是', falseText = '否') {
  return value ? trueText : falseText
})

使用:

<p>{{ isActive | yesNo }}</p>
<p>{{ hasPermission | boolean('有权限', '无权限') }}</p>

默认值

Vue.filter('default', function(value, defaultValue = '-') {
  return value === null || value === undefined || value === '' ? defaultValue : value
})

使用:

<p>{{ nickname | default('匿名用户') }}</p>

完整过滤器集合

const filters = {
  uppercase(value) {
    return value ? value.toUpperCase() : ''
  },
  
  lowercase(value) {
    return value ? value.toLowerCase() : ''
  },
  
  capitalize(value) {
    if (!value) return ''
    return value.charAt(0).toUpperCase() + value.slice(1)
  },
  
  truncate(value, length = 20, suffix = '...') {
    if (!value) return ''
    return value.length > length ? value.slice(0, length) + suffix : value
  },
  
  currency(value, symbol = '¥', decimals = 2) {
    value = Number(value)
    if (isNaN(value)) return ''
    return symbol + value.toFixed(decimals)
  },
  
  thousands(value) {
    value = Number(value)
    if (isNaN(value)) return ''
    return value.toLocaleString()
  },
  
  percentage(value, decimals = 2) {
    value = Number(value)
    if (isNaN(value)) return ''
    return (value * 100).toFixed(decimals) + '%'
  },
  
  fileSize(bytes) {
    if (bytes === 0) return '0 B'
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  },
  
  date(value, format = 'YYYY-MM-DD') {
    const date = new Date(value)
    if (isNaN(date.getTime())) return ''
    
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')
    const seconds = String(date.getSeconds()).padStart(2, '0')
    
    return format
      .replace('YYYY', year)
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hours)
      .replace('mm', minutes)
      .replace('ss', seconds)
  },
  
  relativeTime(value) {
    const date = new Date(value)
    if (isNaN(date.getTime())) return ''
    
    const now = new Date()
    const diff = now - date
    const seconds = Math.floor(diff / 1000)
    const minutes = Math.floor(seconds / 60)
    const hours = Math.floor(minutes / 60)
    const days = Math.floor(hours / 24)
    
    if (seconds < 60) return '刚刚'
    if (minutes < 60) return minutes + '分钟前'
    if (hours < 24) return hours + '小时前'
    return days + '天前'
  },
  
  default(value, defaultValue = '-') {
    return value === null || value === undefined || value === '' ? defaultValue : value
  },
  
  yesNo(value) {
    return value ? '是' : '否'
  }
}

Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

这些过滤器涵盖了常见的使用场景,可以根据项目需求进行调整和扩展。