常用utils

发布时间 2023-08-17 15:36:30作者: 丶乔

1.localStorag

export default {
  set(name,data){
    localStorage.setItem(name,JSON.stringify(data))
  },
  get(name){
    return JSON.parse(localStorage.getItem(name))
  },
  remove(name){
    localStorage.removeItem(name)
  },
  clear(){
    localStorage.clear()
  }
}

2. cookie

cookie的特点:
1.只能使用文本
2 单条存储有大小限制 4KB
3 数量限制(一般浏览器,限制大概在50条左右)
4 读取有域名限制 不可跨域读取,只能由来自 写入cookie的 同一域名 的网页可进行读取。
5 时效限制 每个cookie都有时效,最短的有效期是,会话级别:就是当浏览器关闭,那么cookie立即销毁

$ npm install js-cookie --save

存
//创建简单的cookie
Cookies.set('name', 'value');
//创建有效期为7天的cookie
Cookies.set('name', 'value', { expires: 7 });
//为当前页创建有效期7天的cookie
Cookies.set('name', 'value', { expires: 7, path: '' });

取
Cookies.get('name'); // => 'value'
Cookies.get('nothing'); // => undefined
//获取所有cookie
Cookies.get(); // => { name: 'value' }

删除
Cookies.remove('name');
//如果值设置了路径,那么不能用简单的delete方法删除值,需要在delete时指定路径
Cookies.set('name', 'value', { path: '' });
Cookies.remove('name'); // 删除失败
Cookies.remove('name', { path: '' }); // 删除成功
//注意,删除不存在的cookie不会报错也不会有返回

命名空间
如果担心不小心修改掉Cookies中的数据,可以用noConflict方法定义一个新的cookie。
var Cookies2 = Cookies.noConflict();
Cookies2.set('name', 'value');



JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的。

而cookie是运行在客户端的,所以可以用JS来设置cookie.

一:设置cookie
function setCookie(name,value){
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}

二:获取cookie
function getCookie(name){
    var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
    if(arr=document.cookie.match(reg)){
        return unescape(arr[2]);
    }else{
        return null;
    }
}

三:删除cookie
function delCookie(name){
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval=getCookie(name);
    if(cval!=null){
        document.cookie= name + "="+cval+";expires="+exp.toGMTString();
    } 
}

四: 清除所有cookie   
function clearAllCookie() {
  var date=new Date();
  date.setTime(date.getTime()-10000);
  var keys=document.cookie.match(/[^ =;]+(?=\=)/g);
  console.log("需要删除的cookie名字:"+keys);
  if (keys) {
    for (var i =  keys.length; i--;)
      document.cookie=keys[i]+"=0; expire="+date.toGMTString()+"; path=/";
  }
}

3.随机字符串

/**
 * 生成随机字符串
 */
export function randomString() {
  return Math.random().toString(36).substring(7)
}

4.范围随机数

/**
 * return number[min, max)
 * @param {number} min 范围最小包含
 * @param {number} max 范围最大不包含
 */
export function randomNumber(min, max) {
  return Math.random() * (max - min) + min
}

5.计算年纪

/**
 * calc age
 * @param {String} birthDate - new Date('')
 * @returns {Number}
 */
export function calcAge(birthDate) {
  return Math.abs(
    new Date(Date.now() - new Date(birthDate).getTime()).getUTCFullYear() -
      1970,
  )
}

6.时间格式化

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

//例 --可选择显示字段
parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s} 星期{a}') //2021-03-31 15:07:55 星期三

7.对象转请求参数

/**
 * @param {Object} obj
 * @returns {String}
 */
export function toQueryString(obj) {
  var str = []
  for (var p in obj)
    if (Object.prototype.hasOwnProperty.call(obj, p)) {
      str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]))
    }
  return '?' + str.join('&')
}

//例
toQueryString({a:1,b:2})  // ?a=1&b=2

8.提取地址栏请求参数为对象

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

//例
getQueryObject('https://www.baidu.com?id=123&b=456')  //{id: "123", b: "456"}

9.清除数组中的空值

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

10.toggleClass

传入元素和类名即可,触发后自动取反

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

11.防抖

//使用debounce(funtion, 1000)() //function为要调用的函数 1s只能调用一次

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在,重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

12.深拷贝

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

13.类数组转换为数组并去重

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr))
}

14.检验元素是否拥有某个类名

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。

!!表示,值存在就取值,不存在就取false

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

15.添加、删除元素类名

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

16.请求、响应拦截

//拆分为request文件,请求一层封装

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken, getzyToken } from '@/utils/auth'

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 10000, // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent
    let token = config.url.indexOf('zyapi') > -1 ? getzyToken() : getToken()
    if (config.url.indexOf('zyapi') > -1) {
      config.baseURL = process.env.VUE_APP_BASE_API + 'mz'
      config.url = config.url.split('zyapi')[1]
    } else {
      config.baseURL = process.env.VUE_APP_BASE_API
    }
    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      // config.headers['X-Token'] = getToken()
      config.params = {
        ...config.params,
        token: config.params?.token || token,
      }
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  },
)

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
   */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    if (response.config.responseType === 'blob') return response
    const res = response.data

    // if the custom code is not 20000, it is judged as an error.
    if (res.state !== true) {
      const [code, message] = res.message.split(':')

      Message({
        message: message || 'Error',
        type: 'error',
        duration: 5 * 1000,
        showClose: true,
      })

      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      if (code === 'AUTHORITY-USER-INFO-ERROR-01') {
        // to re-login
        MessageBox.confirm('您已注销,可以留在此页,或重新登录', '确认注销', {
          confirmButtonText: '重新登录',
          cancelButtonText: '留在此页',
          type: 'warning',
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res.body
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: [
        'timeout of 5000ms exceeded',
        'Network Error',
        'Request failed with status code 404',
      ].includes(error.message)
        ? '网络错误,请稍后再试'
        : error.message == 'Request failed with status code 400'
        ? '请求参数出错'
        : error.message,
      type: 'error',
      duration: 8 * 1000,
      showClose: true,
    })
    return Promise.reject(error)
  },
)

export default service

17.验证规则

//拆分为validate文件

/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validUsername(str) {
  const valid_map = ['admin', 'editor']
  return valid_map.indexOf(str.trim()) >= 0
}

/**
 * @param {string} url
 * @returns {Boolean}
 */
export function validURL(url) {
  const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
  return reg.test(url)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validLowerCase(str) {
  const reg = /^[a-z]+$/
  return reg.test(str)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validUpperCase(str) {
  const reg = /^[A-Z]+$/
  return reg.test(str)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function validAlphabets(str) {
  const reg = /^[A-Za-z]+$/
  return reg.test(str)
}

/**
 * @param {string} email
 * @returns {Boolean}
 */
export function validEmail(email) {
  const reg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
  return reg.test(email)
}

/**
 * @param {string} str
 * @returns {Boolean}
 */
export function isString(str) {
  if (typeof str === 'string' || str instanceof String) {
    return true
  }
  return false
}

/**
 * @param {Array} arg
 * @returns {Boolean}
 */
export function isArray(arg) {
  if (typeof Array.isArray === 'undefined') {
    return Object.prototype.toString.call(arg) === '[object Array]'
  }
  return Array.isArray(arg)
}

/**
 * 密码验证
 * @param {string} str
 * @returns {Boolean}
 */

export function isPassword(str) {
  const reg = /^[0-9a-zA-Z]{6,18}$/
  return reg.test(str)
}

/**
 * 账号验证
 * @param {string} str
 */
export function isAccount(str) {
  const reg = /^[a-zA-Z]([-_a-zA-Z0-9]{5,19})$/
  return reg.test(str)
}

/**
 * 手机号码
 * @param {string} str
 */
export function isPhoneNumber(str) {
  const reg = /^1\d{10}$/
  return reg.test(str)
}

/**
 * 简单的身份证号码验证
 * @param {string} str
 */
export function isIDNumber(str) {
  const reg = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
  return reg.test(str)
}

/**
 * 邮箱格式验证
 * @param {string} email
 */
export function validateEmail(email) {
  const strRegex = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
  if(!strRegex.test(email)){
    console.log('Email format error');
    return	
  }
}