前端工具函數

將一級的數據結構處理成樹狀數據結構

處理成樹狀結構,通常就是須要節點和父節點標識,或者須要考慮以哪一個節點爲根節點生成樹結構數據git

// 使用示例代碼:
list: [{id: 1, pid: 0, name: 11}, {id: 2, pid: 1, name: 2}]
getTreeArr({ key: 'id', pKey: 'pid', data: list })
result: [
    {id: 1, pid: 0, name: 11, children: [
        {id: 2, pid: 1, name: 2}
    ]}
]
複製代碼
/**
 * 將一級的數據結構處理成樹狀數據結構
 * @param {Object} obj {key, pKey, data}
 *  @param obj.key  字段名稱 好比id
 *  @param obj.pKey 父字段名稱 好比 pid
 *  @param obj.rootPValue 根節點的父字段的值
 *  @param obj.data 須要處理的數據
 *  @param obj.jsonData 是否深複製數據(默認是true)
 * @return {Array} arr
   */
  getTreeArr: (obj) => {
    if (!Array.isArray(obj.data)) {
      console.log('getTreeArr=>請傳入數組')
      return []
    }
    obj.jsonData = obj.jsonData === false ? obj.jsonData : true
    const arr = obj.jsonData ? JSON.parse(JSON.stringify(obj.data)) : obj.data
    const arr1 = []
    // 將數據處理成數狀結構
    arr.forEach(item => {
      let index = 0
      item.children = []
      arr.forEach(item1 => {
        // 獲得樹結構關係
        if (item[obj.key] === item1[obj.pKey]) {
          item.children.push(item1)
        }
        // 判斷根節點
        if (item1[obj.key] !== item[obj.pKey]) {
          index++
        }
      })
      // 沒傳入根節點,根據當前數據結構獲得根節點
      if (!('rootPValue' in obj) && index === arr.length) {
        arr1.push(item)
      }
    })
    // 傳入根節點,根據傳入的根節點組成樹結構
    if ('rootPValue' in obj) {
      arr.forEach(item => {
        if (item[obj.pKey] === obj.rootPValue) {
          arr1.push(item)
        }
      })
    }
    return arr1
  }
複製代碼

數組去重

數組去重方法有許多,還分爲普通數組和對象數組,這裏列舉了一些,並把其中優缺點分析了一下github

/**
   * 數組去重
   * @param {Array} data 要去重的數組
   * @param {String} key 做爲去重依據的字段 (處理對象數組時須要傳入)
   * @return arr 返回處理後的數據
   */
複製代碼

根據對象的屬性不一樣去重

推薦使用element-ui

handleRepeatArr ({ data, key }) {
    if (!Array.isArray(data)) {
      console.log('請傳入數組')
      return
    }
    const arr = []; const obj = {}
    data.forEach((item, index) => {
      const attr = key ? item[key] : item
      if (!obj[attr]) {
        obj[attr] = index + 1
        arr.push(item)
      }
    })
    return arr
  }
複製代碼

遞歸去重

缺點:會將數據默認排序json

handleRepeatArr ({ data, key }) {
    if (!Array.isArray(data)) {
      console.log('請傳入數組')
      return
    }
    /** 1.遞歸去重,缺點,會將數據默認排序 */
    // 先對數據作排序處理
    data = data.sort((item, item1) => {
      if (key) {
        return item[key] - item1[key]
      }
      return item - item1
    })
    // 遞歸去重
    function getData (index) {
      if (index >= 1) {
        // 判斷當前數據和下一條數據是否相等
        let result = key ? data[index][key] === data[index - 1][key] : data[index] === data[index - 1]
        if (result) {
          data.splice(index, 1)
        }
        getData(index - 1)
      }
    }
    getData(data.length - 1)
    return data
  }
複製代碼

利用indexOf以及forEach

缺點:適合處理數組,不適合處理對象數組數組

handleRepeatArr ({ data, key }) {
    if (!Array.isArray(data)) {
      console.log('請傳入數組')
      return
    }
    let arr = []
    data.forEach((item, index) => {
      // 若是當前元素在以後沒有出現過(後面出現的數據會保留)
      // let result = data.indexOf(item, index + 1)
      // 若是當前元素在以前沒有出現過(前面出現的數據會保留)
      let result = index === 0 ? -1 : data.lastIndexOf(item, index - 1)
      if (result === -1) {
        arr.push(item)
      }
    })
    return arr
  }
複製代碼

new Set

缺點:適合處理數組,不適合處理對象數組瀏覽器

return [...new Set(data)]
複製代碼

雙層循環去重

缺點:佔用內存高bash

handleRepeatArr ({ data, key }) {
    if (!Array.isArray(data)) {
      console.log('請傳入數組')
      return
    }
    for (let i = 0, len = data.length; i < len; i++) {
      for (let j = i + 1; j < len; j++) {
        let result = key ? data[i][key] === data[j][key] : data[i] === data[j]
        if (result) {
          data.splice(j, 1)
          len--
          j--
        }
      }
    }
    return data
  }
複製代碼

複製內容

複製成功後若是須要提示,須要自定義相關回調,當前函數使用的是element-ui的彈窗服務器

/**
   * 複製
   * @param {String} value 要複製的值
   */
  copyData (value) {
    const inputDom = document.createElement('input')
    inputDom.value = value
    document.body.appendChild(inputDom)
    inputDom.select() // 選擇對象
    document.execCommand('Copy') // 執行瀏覽器複製命令
    document.body.removeChild(inputDom) // 刪除DOM
    Message({
      type: 'success',
      message: '複製成功'
    })
  }
複製代碼

a模擬window.open打開窗口

由於有些瀏覽器會默認攔截window.open,當須要函數中打開窗口,可使用a標籤模擬window.open數據結構

/**
   * a模擬window.open,不會被瀏覽器攔截
   * @param {String} url        a標籤打開的地址
   * @param {String} id         a標籤的ID
   * @param {String} targetType a標籤點擊打開的方式(當前頁面打開仍是新窗口打開)
   */
  openWindow: (url, targetType = '_blank', id = 'open', download = false) => {
    // 若是存在則刪除
    if (document.getElementById(id)) {
      document.body.removeChild(document.getElementById(id))
    }
    const a = document.createElement('a')
    a.setAttribute('href', url)
    if (download) {
      a.setAttribute('download', url)
    }
    a.setAttribute('target', targetType)
    a.setAttribute('id', id)
    document.body.appendChild(a)
    a.click()
  }
複製代碼

獲得想要的時間格式

這個在業務中用的比較頻繁app

// 使用示例代碼:
switchTime(new Date(), 'YYYY-MM-DD hh') // 返回 2019-05-22 11
switchTime(new Date(), 'YYYYMMDD hh:mm:ss') // 返回 20190522 11:00:00
複製代碼
/**
   * 傳入時間戳,轉換指定的時間格式
   * @param {Number} val      時間戳
   * @param {String} dateType 要獲得的時間格式 例如 YYYY-MM-DD hh:mm:ss
   * @return dataStr 例如 YYYY-MM-DD hh:mm:ss
   */
  switchTime: (val = +new Date(), dateType = 'YYYY-MM-DD hh:mm:ss') => {
    // 將字符串轉換成數字
    const timeStamp = +new Date(val)

    // 若是轉換成數字出錯
    if (!timeStamp) {
      return val
    }
    let str
    // 獲得時間字符串
    const dateStr = new Date(timeStamp)
    str = dateType.replace('YYYY', dateStr.getFullYear())
    str = str.replace('MM', (dateStr.getMonth() + 1 < 10 ? '0' : '') + (dateStr.getMonth() + 1))
    str = str.replace('DD', (dateStr.getDate() < 10 ? '0' : '') + dateStr.getDate())
    str = str.replace('hh', (dateStr.getHours() < 10 ? '0' : '') + dateStr.getHours())
    str = str.replace('mm', (dateStr.getMinutes() < 10 ? '0' : '') + dateStr.getMinutes())
    str = str.replace('ss', (dateStr.getSeconds() < 10 ? '0' : '') + dateStr.getSeconds())

    return str
  }
複製代碼

時間顯示轉換

這個方法中須要應用到上一個方法,獲取當前時間,或者能夠自行獲得時間而後再去處理

假設當前時間爲 2019-05-20 00:00:00
// 使用示例代碼:
timeView(new Date()) // 剛剛發佈
timeView('2019-05-19 23:01:00') // 59分鐘前
timeView('2019-05-19 12:00:00') // 12小時前
timeView('2019-05-15 12:00:00') // 5天前
timeView('2019-04-15 12:00:00') // 04-15
timeView('2018-04-15 12:00:00') // 2018-04-15
複製代碼
/**
   * 時間顯示
   */
  timeView: function (val) {
    const now = +new Date() // 當時時間
    const timeStamp = +new Date(val) // 須要處理的時間
    const result = now - timeStamp // 相差的時間戳
    const min = 60 * 1000 // 分鐘的毫秒數
    const hour = 60 * 60 * 1000 // 小時的毫秒數
    const day = 60 * 60 * 1000 * 24 // 日的毫秒數
    if (result / min < 1) {
      return '剛剛發佈'
    } else if (result / min < 60) {
      return Math.floor(result / min) + '分鐘前'
    } else if (result / hour > 1 && result / hour < 24) {
      return Math.floor(result / hour) + '小時前'
    } else if (result / day > 1 && result / day < 7) {
      return Math.floor(result / day) + '天前'
    } else if (this.switchTime(now, 'YYYY') === this.switchTime(timeStamp, 'YYYY')) {
      return this.switchTime(timeStamp, 'MM月DD日')
    } else {
      return this.switchTime(timeStamp, 'YYYY年MM月DD日')
    }
  }
複製代碼

處理搜索欄參數

getLocationSearch () {
    const str = window.location.search
    const arr = str.substr(1).split('&')
    const obj = {}
    for (const item of arr) {
      const data = item.split('=')
      obj[data[0]] = data[1]
    }
    return obj
  }
複製代碼

文件大小顯示轉換

// 使用示例代碼:
bytesToSize(12) // 12.0 B
bytesToSize(683468) // 667 KB
bytesToSize(4544) // 4.44 KB
bytesToSize(98223445) // 93.7 MB
bytesToSize(9822344566) // 9.15 GB
複製代碼
bytesToSize (bytes) {
    if (bytes === 0) return '0 B'
    var k = 1024 // or 1024
    var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
    var i = Math.floor(Math.log(bytes) / Math.log(k))
    return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
  }
複製代碼

對請求失敗的HTTP狀態碼作處理

/**
   * 對請求失敗的HTTP狀態碼作處理
   * @param {Number} code     HTTP狀態碼
   * @param {String} message  錯誤提示
   * @return message 返回處理過的提示信息
   */
  requestError: (code, message) => {
    const statusCode = (code + '').replace(/[^0-9]+/g, '') - 0

    switch (statusCode) {
      case 400:
        return 'Bad Request (錯誤的請求)'
      case 401:
        return 'Unauthorized (請求要求身份驗證)'
      case 403:
        return 'Forbidden (服務器拒絕請求)'
      case 404:
        return 'NOT Found (服務器找不到請求的資源)'
      case 405:
        return 'Bad Request (禁用請求中指定的方法)'
      case 406:
        return 'Not Acceptable (沒法使用請求的內容特性響應請求的網頁)'
      case 407:
        return 'Proxy Authentication Required (須要代理受權)'
      case 408:
        return 'Request Timed-Out (服務器等候請求時發生超時)'
      case 409:
        return 'Conflict (服務器在完成請求時發生衝突。服務器必須在響應中包含有關衝突的信息)'
      case 410:
        return 'Gone (請求的資源已被永久刪除)'
      case 411:
        return 'Length Required (服務器不接受不含有效內容長度標頭字段的請求)'
      case 412:
        return 'Precondition Failed (未知足前提條件)'
      case 413:
        return 'Request Entity Too Large (請求實體過大)'
      case 414:
        return 'Request, URI Too Large (請求的 URI 過長)'
      case 415:
        return 'Unsupported Media Type (不支持的媒體類型)'
      case 429:
        return '您的操做過於頻繁,請稍後重試'
      case 500:
        return 'Internal Server Error (服務器內部錯誤)'
      case 501:
        return 'Not Implemented (還沒有實施)'
      case 502:
        return 'Bad Gateway (錯誤網關)'
      case 503:
        return 'Server Unavailable (服務不可用)'
      case 504:
        return 'Gateway Timed-Out (網關超時)'
      case 505:
        return 'HTTP Version not supported (HTTP 版本不受支持)'
      default:
        return message
    }
  }
複製代碼

經過key找到在列表中對應的名字

// 使用示例代碼:
list: [{key: '紅色', value: 1}]
getDataName({dataList: list, value: 'value', label: 'key', data: 1}) // 紅色
複製代碼
/**
   * 經過key找到在列表中對應的顯示
   * @param {Object} obj
   *  @param obj.dataList 數據列表
   *  @param obj.value    數據的值對應的字段名稱   例如 'value'
   *  @param obj.label    數據的說明對應的字段名稱 例如 'label'
   *  @param obj.data     當前傳入的數據值
   * @return name        返回當前傳入值在數組中對應的名字
   */
  getDataName: (obj) => {
    let name = obj.data
    if (Array.isArray(obj.dataList) && obj.dataList.length > 0) {
      for (let i = 0; i < obj.dataList.length; i++) {
        if (obj.dataList[i][obj.value] === obj.data) {
          name = obj.dataList[i][obj.label]
        }
      }
    }
    return name
  }
複製代碼

代碼地址

工具庫地址

更多

編寫一個驗證函數

相關文章
相關標籤/搜索