小程序中应用filter转换数据

141 阅读2分钟

在vue2中转换状态类型这种常用的键值数据时,我们可以通过过滤器filter 很方便的转换。但是在vue3(取消了filter)或者其他项目中,一般都是对每组数据写一个转换方法,方法中通过if/else 或者 switch 进行取值,效率更高的方法是通过对象取key的方式(obj[key])来获取。这样对每一组数据都需要写一个方法来转换,很麻烦,我们可以编写一个方法来统一获取数据,只要传入过滤名称即可。

1. 简单过滤器

  1. 定义数据:filter/const.js
// 证件类型
export const cardTypeData = {
  0: '身份证',
  1: '护照',
  default: '',
}
  1. 自定义方法中处理:utils/func.js
import * as filterConst from '../filter/const'

/**
 * filter过滤器
 * @param filterName  过滤器名称
 * @param key 键
 */
export const filter = (filterName, key) => {
  const data = filterConst[`${filterName}Data`]
  return data[key] || data.default
}
  1. 使用
import { filter } from '../../utils/func'
Page({
  data(){
    myCardType: filter('cardType', 0) // 身份证
  }
})

2. 过滤器中数据的使用

上面 filter/const.js 文件中定义了转换的数据,这个数据不光在转换时使用,很多类型、状态需要在表单页面中的下拉选择框中使用。我们也可以直接拿到。

  1. 转换数据的方法
/* 将const中的数据转化为下拉框选择时可用的数组
*  isNumber key是否是number类型
*/
export const constDataToArray = (obj, firstItem = null, isNumber = false) => {
  const arr = []
  if (isNumber) {
    Object.getOwnPropertyNames(obj).forEach(k => {
      if (k !== 'default') {
        arr.push({ value: Number(k), label: obj[k] })
      }
    })
  } else {
    Object.getOwnPropertyNames(obj).forEach(k => {
      if (k !== 'default') {
        arr.push({ value: k, label: obj[k] })
      }
    })
  }
  firstItem && arr.unshift(firstItem)
  return arr
}
  1. 获取数据
import { cardTypeData } from '../../filter/const'
import { constDataToArray } from '../../utils/func'
Page({
  data(){
    cardTypeList = constDataToArray(cardTypeData, null, true)
  }
})
  1. 数据格式 像上面拿到的证件列表数据如下,可以再页面的选择列表中直接使用。
[
  {value: 0, label: '身份证'},
  {value: 1, label: '护照'},
]

3. 其他数据的转换

在我使用vue2中的filter时,不止键值转换的数据使用过滤器来转换,对一些常用的格式化方法,也可以使用过滤器,当时每种格式化都写了方法,现在也可以放到我们的filter方法中,只需要传递格式化名称即可。

  1. 定义格式化方法:filter/func.js
export default {
  month: t => {
    if (t) {
      // getTimeItem获取到 年月日时分秒
      const { year, month } = getTimeItem(t)
      return `${year}-${month}`
    }
    return ''
  },
  date: t => {
    if (t) {
      const { year, month, day } = getTimeItem(t)
      return `${year}-${month}-${day}`
    }
    return ''
  },
  ...
}
  1. 定义转换方法
import filterFunc from '../filter/func'

/**
 * filter过滤器
 * @param filterName  过滤器名称
 * @param args 参数
 */
export const filter = (filterName, ...key) => {
  return filterFunc[filterName] ? filterFunc[filterName](...args) : ''
}
  1. 使用
import { filter } from '../../utils/func'
Page({
  data(){
    date: filter('date', new Date())
  }
})

4. 整合

上面的键值转换和格式化方法可以合并在一个filter方法中,最后的代码如下:

  1. 方法库:utils/func.js
import * as filterConst from '../filter/const'
import filterFunc from '../filter/func'

/**
 * filter过滤器
 * @param filterName  过滤器名称
 * @param args 参数
 */
export const filter = (filterName, ...args) => {
  const data = filterConst[`${filterName}Data`]
  if (data) {
    return data[args[0]] || data.default
  }
  return filterFunc[filterName] ? filterFunc[filterName](...args) : ''
}
  1. 过滤器方法 filter/const.js

下面是我常用的一下格式化方法

/*
 * @Descripttion: 过滤器方法
 * @Author: pujianguo
 * @Date: 2020-12-23 16:25:53
 *
 * 通过filter()方法转换
 * eg: filter(new Date(), 'date'), 结果为当前日期
 */
export default {
  /** *************** 时间相关 *************** **/
  month: t => {
    if (t) {
      const { year, month } = getTimeItem(t)
      return `${year}-${month}`
    }
    return ''
  },
  date: t => {
    if (t) {
      const { year, month, day } = getTimeItem(t)
      return `${year}-${month}-${day}`
    }
    return ''
  },
  minute: t => {
    if (t) {
      const { year, month, day, hour, minute } = getTimeItem(t)
      return `${year}-${month}-${day} ${hour}:${minute}`
    }
    return ''
  },
  second: t => {
    if (t) {
      const { year, month, day, hour, minute, second } = getTimeItem(t)
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`
    }
    return ''
  },

  /** *************** 数据相关 *************** **/
  // 保留小数位的数据展示,结果为字符串
  decimalString: (value, decimals = 2) => {
    value = parseFloat(value)
    value = Number.isNaN(value) ? 0 : value
    return value.toFixed(decimals)
  },
  // 保留小数的浮点型,末尾的0会被自动省略
  decimalFloat (value, decimals = 2) {
    return parseFloat(this.decimalString(value, decimals))
  },
  // 将结果处理为整形,非数字为0。Number('a')、parseInt('a') 结果都是NaN
  int (value) {
    value = parseInt(value)
    return Number.isNaN(value) ? 0 : value
  },
}

const getTimeItem = t => {
  const date = new Date(t)
  return {
    year: date.getFullYear(),
    month: formatNumber(date.getMonth() + 1),
    day: formatNumber(date.getDate()),
    hour: formatNumber(date.getHours()),
    minute: formatNumber(date.getMinutes()),
    second: formatNumber(date.getSeconds()),
  }
}
const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}
  1. 过滤器数据 filter/const.js
/*
 * @Descripttion: 过滤器数据
 * @Author: pujianguo
 * @Date: 2020-12-23 15:52:54
 *
 * 通过filter()方法转换
 * eg: filter(0, 'cardType'), 结果为身份证
 */

// 证件类型
export const cardTypeData = {
  0: '身份证',
  1: '护照',
  2: '军人身份证',
  6: '社会保障卡',
  A: '武装警察身份证',
  B: '港澳通行证',
  C: '台湾居民来往大陆通行证',
  E: '户口簿',
  F: '临时身份证',
  P: '外国人永久居留证',
  default: '',
}

...
  1. 使用
import { filter, constDataToArray } from '../../utils/func'
import { cardTypeData } from '../../filter/const'

Page({
  data(){
    date: filter('date', new Date()),
    myCardType: filter('cardType', 0),
    cardTypeList = constDataToArray(cardTypeData, null, true)
  }
})

5. 结语

以上只是本人在使用中的一些总结,如有更好的方案请指教。