Vue 过滤器(filters)的使用、封装、批量全局定义及常用实例分享

Filters.png Vue 过滤器(filters)的使用、封装、批量全局定义及常用实例分享 经验总结

Vue 提供了自定义过滤器(filters)方法,可以对文本按需格式化。

可以用在 双花括号插值和 v-bind 表达式,其中 v-bind 从 2.1.0+ 开始支持。

使用方法如下,在 JavaScript 表达式尾部,用 | 隔开:

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 v-bind 中 -->
<div v-bind:id="rawId | formatId"></div>

定义一个过滤器:

可以在 .vue 页面中直接定义

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

也可以在创建 Vue 实例前,全局定义过滤器:

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

new Vue({
  // ...
})

*注: 当全局过滤器和局部过滤器重名时,会采用局部过滤器。

过滤器支持串联:

{{ message | filterA | filterB }}

该实例中,filterAmessage 格式化后将结果传给 filterB 再进行转换。

过滤器是 JavaScript 函数,因此还可以接收参数:

{{ message | filterA('arg1', arg2) }}

filterA 作为过滤器分别接收 messagearg1arg2 三个参数。

封装一个过滤器:

@/plugins/filters.js

export const filterA = (arg1, arg2) => {
  ...
}

在页面中使用:

page.vue

<template>
  <div>{{ message | filterA(arg1, arg2) }}</div>
</template>

<script>
import { filterA } from '@/plugins/filters'

export default {
  filters: {
    filterA,
  },
  data() {
    return {
      message: 'www.w3h5.com',
    }
  },
}
</script>

批量全局使用:

/main.js

import * as Filters from '@/plugins/filters'

// 放在在 Vue 实例之前
Object.keys(Filters).forEach(key => {
  Vue.filter(key, Filters[key]);
 })

然后就可以在页面中直接使用了:

<template>
  <div>{{ message | filterA(arg1, arg2) }}</div>
</template>

常用过滤器实例:

filters.js

/*
 * Vue Filters
 * @see https://cn.vuejs.org/v2/guide/filters.html
 */

/**
 * 字符串重复
 * @param {String|Number} value
 * @param {Number} count
 */
export const repeat = (value, count) => value.toString().repeat(count)

/**
 * 字符串替换
 * @param {String|Number} value
 * @param {String} string
 * @param {String} replacement
 */
export const replace = (value, string, replacement) => value.toString().replace(new RegExp(string, 'g'), replacement)

/**
 * 手机号隐私保护
 * 13866668888 -> 138****8888
 * @param {String|Number} value
 */
export const secretPhone = (value) => value.toString().replace(/(/d{3})(/d{4})(/d{4})/, '$1****$3')

/**
 * 格式化手机号
 * 13866668888 -> "138-6666-8888"
 * @param {*} value
 */
export const formatPhone = (value) => value.toString().replace(/(^/d{3}|/d{4}/B)/g, '$1-')

/**
 * 字母大小写转换
 * type: 1-首字母大写 2-首页母小写 3-全部大写 4-全部小写 5-大小写转换
 * @param {String} value
 * @param {Number} type
 */
export const changeCase = (value, type) => {
  // 大小写转换
  const toggleCase = (value) => {
    let newValue = ''
    value.split('').forEach((item) => {
      if (/^([a-z]+)/.test(item)) {
        newValue += item.toUpperCase()
      } else if (/^([A-Z]+)/.test(item)) {
        newValue += item.toLowerCase()
      } else {
        newValue += item
      }
    })
    return newValue
  }

  switch (type) {
    case 1:
      return value.charAt(0).toUpperCase() + value.slice(1)
    case 2:
      return value.charAt(0).toLowerCase() + value.slice(1)
    case 3:
      return value.toUpperCase()
    case 4:
      return value.toLowerCase()
    case 5:
      return toggleCase(value)
    default:
      return value
  }
}

/**
 * 去除空格
 * type: 1-前后空格 2-前空格 3-后空格 4-所有空格
 * @param {String} value
 * @param {Number} type
 */
export const trim = (value, type) => {
  switch (type) {
    case 1:
      return value.replace(/(^/s*)|(/s*$)/g, '')
    case 2:
      return value.replace(/(^/s*)/g, '')
    case 3:
      return value.replace(/(/s*$)/g, '')
    case 4:
      return value.replace(//s+/g, '')
    default:
      return value
  }
}

/**
 * 日期时间格式化
 * {{ Date() | formatDate }} -> 2020-09-28 15:54:52
 * {{ '2020/10/01 12:30:45' | formatDate('yyyy-MM-dd hh:mm:ss w') }} -> 2020-10-01 12:30:45 星期四
 * @param {Date} value 可以被 new Date(value) 解析的时间格式,如 Date()、2020/10/01、2020-10-01 12:00 等
 * @param {String} fmt 格式化模版
 */
export const formatDate = (value, fmt = 'yyyy-MM-dd hh:mm:ss') => {
  const date = new Date(value)
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'w+': date.getDay(), // 星期
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
  }

  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  }

  for (var k in o) {
    if (k === 'w+') {
      if (o[k] === 0) {
        fmt = fmt.replace('w', '星期日')
      } else if (o[k] === 1) {
        fmt = fmt.replace('w', '星期一')
      } else if (o[k] === 2) {
        fmt = fmt.replace('w', '星期二')
      } else if (o[k] === 3) {
        fmt = fmt.replace('w', '星期三')
      } else if (o[k] === 4) {
        fmt = fmt.replace('w', '星期四')
      } else if (o[k] === 5) {
        fmt = fmt.replace('w', '星期五')
      } else if (o[k] === 6) {
        fmt = fmt.replace('w', '星期六')
      }
    } else if (new RegExp(`(${k})`).test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length),
      )
    }
  }

  return fmt
}

/**
 * 文件大小显示转换
 * 12         -> 12.0 B
 * 98223445   -> 93.7 MB
 * 9822344566 -> 9.15 GB
 * @param {String|Number} bytes
 */
export const bytesToSize = (bytes) => {
  bytes = bytes.toString()
  if (bytes == 0) return '0 B'
  const k = 1024
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
}

/**
 * 千分位格式化
 * 1234567 -> 1,234,567
 * @param {String|Number} value
 */
export const thousands = (value, fractionDigits = 0) => {
  const regexp = //d{1,3}(?=(/d{3})+(/./d*)?$)/g
  return (Number(value).toFixed(fractionDigits) + '').replace(regexp, '$&,')
}

/**
 * 现金数字转大写
 * 1234.567 -> 壹仟贰佰叁拾肆元伍角陆分柒厘
 * @param {String|Number} value
 */
export const upDigit = (value) => {
  const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  const fraction = ['角', '分', '厘']
  const unit = [
    ['元', '万', '亿'],
    ['', '拾', '佰', '仟'],
  ]
  let s = ''
  let head = value < 0 ? '欠' : ''
  value = Math.abs(value)

  for (let i = 0; i < fraction.length; i++) {
    s += (digit[Math.floor(value * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '')
  }

  s = s || '整'
  value = Math.floor(value)

  for (let i = 0; i < unit[0].length && value > 0; i++) {
    let p = ''
    for (let j = 0; j < unit[1].length && value > 0; j++) {
      p = digit[value % 10] + unit[1][j] + p
      value = Math.floor(value / 10)
    }
    s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s
  }

  return (
    head +
    s
      .replace(/(零.)*零元/, '元')
      .replace(/(零.)+/g, '零')
      .replace(/^整$/, '零元整')
  )
}

参考文献:

分享一些常用的 Vue filters

VUE全局过滤器filter

未经允许不得转载:w3h5 » Vue 过滤器(filters)的使用、封装、批量全局定义及常用实例分享

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/150534.html

(0)
上一篇 2021年9月13日 01:07
下一篇 2021年9月13日 01:07

相关推荐

发表回复

登录后才能评论