Skip to content

替换树状穿梭框数据源中的key名字

js
const replaceKey = (list) => {
     const arr = []
     list.forEach(item => {
       const obj = {}
       for (const k in item) {
         if (item[k] instanceof Array) {
           obj[k] = replaceKey(item[k])
         } else {
           if (k === 'name') {
             obj['title'] = item[k]
           } else if (k === 'bzkid') {
             obj['key'] = item[k]
           } else {
             obj[k] = item[k]
           }
         }
       }
       arr.push(obj)
     })
     return arr
   }
const replaceKey = (list) => {
     const arr = []
     list.forEach(item => {
       const obj = {}
       for (const k in item) {
         if (item[k] instanceof Array) {
           obj[k] = replaceKey(item[k])
         } else {
           if (k === 'name') {
             obj['title'] = item[k]
           } else if (k === 'bzkid') {
             obj['key'] = item[k]
           } else {
             obj[k] = item[k]
           }
         }
       }
       arr.push(obj)
     })
     return arr
   }

扁平化树状数据源

js
const flatten = (list = [],childrenField='children') => {
  let newList = []
  list.forEach(item => {
    const {[childrenField]:children,...rest} = item
    newList.push(rest)
    if(children&&children.length){
     newList=[...newList,...flatten(children)] 
    }
  })
  return newList
}
const flatten = (list = [],childrenField='children') => {
  let newList = []
  list.forEach(item => {
    const {[childrenField]:children,...rest} = item
    newList.push(rest)
    if(children&&children.length){
     newList=[...newList,...flatten(children)] 
    }
  })
  return newList
}

接收文件流下载文件

js
async download (record) {
      var params = {
        uuid: record.uuid
      }
      try {
        const res = await download(params)
        const blob = new Blob([res], {})
        if (window.navigator.msSaveOrOpenBlob) {
          navigator.msSaveBlob(blob, record.fjmc)
        } else {
          var link = document.createElement('a')
          var href = window.URL.createObjectURL(blob)
          link.setAttribute('href', href)
          link.setAttribute('download', record.fjmc)
       	  // 触发a的单击事件
          // link.click()
          let event = new MouseEvent('click');
          link.dispatchEvent(event);
          //移除a连接
          window.URL.revokeObjectURL(link.href)
        }
      } catch (err) {
        console.log(err)
      }
    },
async download (record) {
      var params = {
        uuid: record.uuid
      }
      try {
        const res = await download(params)
        const blob = new Blob([res], {})
        if (window.navigator.msSaveOrOpenBlob) {
          navigator.msSaveBlob(blob, record.fjmc)
        } else {
          var link = document.createElement('a')
          var href = window.URL.createObjectURL(blob)
          link.setAttribute('href', href)
          link.setAttribute('download', record.fjmc)
       	  // 触发a的单击事件
          // link.click()
          let event = new MouseEvent('click');
          link.dispatchEvent(event);
          //移除a连接
          window.URL.revokeObjectURL(link.href)
        }
      } catch (err) {
        console.log(err)
      }
    },

二进制流转blob

js
const blob=new Blob([res],{type:'application/vnd.ms-excel'})//xlxs
const blob=new Blob([res],{type:'zip;charset=utf-8'})//zip
const blob=new Blob([res],{type:'application/vnd.ms-excel'})//xlxs
const blob=new Blob([res],{type:'zip;charset=utf-8'})//zip

blob转base64算法

js
getBase64 (file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => resolve(reader.result)
        reader.onerror = error => reject(error)
      })
    }
getBase64 (file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => resolve(reader.result)
        reader.onerror = error => reject(error)
      })
    }

base64转二进制流

js
//base64解析为二进制 入参base64t图片
const base64Parser = (dataURL) => {
  const base64Regex =/^data:image\/(png|jpg|svg|svg\+xml);base64,/
  if (typeof dataURL !== "string" ||!base64Regex.test(dataURL)) return false
  const stringBase64 = dataURL.replace(base64Regex, "")
  const binaryString = window.atob(stringBase64)
  const len = binaryString.length
  const bytes = new Uint8Array(len)
  for (let i = 0; i < len; i++){
    const ascii = binaryString.charCodeAt(i)
    bytes[i] = ascii
  }
  return bytes.buffer
}
//base64解析为二进制 入参base64t图片
const base64Parser = (dataURL) => {
  const base64Regex =/^data:image\/(png|jpg|svg|svg\+xml);base64,/
  if (typeof dataURL !== "string" ||!base64Regex.test(dataURL)) return false
  const stringBase64 = dataURL.replace(base64Regex, "")
  const binaryString = window.atob(stringBase64)
  const len = binaryString.length
  const bytes = new Uint8Array(len)
  for (let i = 0; i < len; i++){
    const ascii = binaryString.charCodeAt(i)
    bytes[i] = ascii
  }
  return bytes.buffer
}

获取base64图片的属性

js
let newImage = new Image()
// 这里将src传入需要获取信息的图片地址或base64
newImage.src = base64
// onload是异步的,封装的话可以用promise
newImage.onload = () => {
  // 输出图片信息 比如可以获取图片宽高
  console.log(newImage)
  console.log(newImage.width)
  console.log(newImage.height)
}
let newImage = new Image()
// 这里将src传入需要获取信息的图片地址或base64
newImage.src = base64
// onload是异步的,封装的话可以用promise
newImage.onload = () => {
  // 输出图片信息 比如可以获取图片宽高
  console.log(newImage)
  console.log(newImage.width)
  console.log(newImage.height)
}

下划线与驼峰互转

js
// 下划线转换驼峰
function toHump(name) {
    return name.replace(/\_(\w)/g, function(all, letter){
        return letter.toUpperCase();
    });
}
// 驼峰转换下划线
function toLine(name) {
  return name.replace(/([A-Z])/g,"_$1").toLowerCase();
}
// 下划线转换驼峰
function toHump(name) {
    return name.replace(/\_(\w)/g, function(all, letter){
        return letter.toUpperCase();
    });
}
// 驼峰转换下划线
function toLine(name) {
  return name.replace(/([A-Z])/g,"_$1").toLowerCase();
}

截取去除路由base,并在新窗口中打开路由

js
let path = 需要跳转的路由
let base = window.location.href
base = base.substring(0,base.indexOf('基路由地址'))
window.open(base+path,'_blank')
let path = 需要跳转的路由
let base = window.location.href
base = base.substring(0,base.indexOf('基路由地址'))
window.open(base+path,'_blank')

根据id找出树结构数据中的对应项

js
@输入参数 id: 要查找数据对应的id
@输入参数 list: 要查询的树形结构数组
@输出:返回该数据或null
// 方法一
function findItemById(id, list) {
  let res = list.find(item => item.id == id)
  if (res) {
    return res
  } else {
      list.forEach(item=>{
          if(item.children instanceof Array && item.children.length>0){
              const subRes = findItemById(id,item.children)
              if(subRes){
                  res = subRes
              }
          }
      })
    /*for (let i=0; i<list.length; i++) {
      if (list[i].children instanceof Array && list[i].children.length > 0) {
        res = findItemById(id, list[i].children)
        if(res){
          return res
        }
      }
    }*/
   // return null
   return res 
  }
}
// 方法二
function findItemById(id: string, list: any) {
  for (const node of list) {
    if (node.id === id) {
      return node
    }
   if(node.children){
      const foundNode: any = findItemById(id, node.children)
      if (foundNode) {
          return foundNode
      }
   }
  }
  return null
}
@输入参数 id: 要查找数据对应的id
@输入参数 list: 要查询的树形结构数组
@输出:返回该数据或null
// 方法一
function findItemById(id, list) {
  let res = list.find(item => item.id == id)
  if (res) {
    return res
  } else {
      list.forEach(item=>{
          if(item.children instanceof Array && item.children.length>0){
              const subRes = findItemById(id,item.children)
              if(subRes){
                  res = subRes
              }
          }
      })
    /*for (let i=0; i<list.length; i++) {
      if (list[i].children instanceof Array && list[i].children.length > 0) {
        res = findItemById(id, list[i].children)
        if(res){
          return res
        }
      }
    }*/
   // return null
   return res 
  }
}
// 方法二
function findItemById(id: string, list: any) {
  for (const node of list) {
    if (node.id === id) {
      return node
    }
   if(node.children){
      const foundNode: any = findItemById(id, node.children)
      if (foundNode) {
          return foundNode
      }
   }
  }
  return null
}

实现文件上传进度

js
// 文件上传接口,添加onUploadProgress获取上传进度信息
export function apiImport (data,onUploadProgress) {
  return request({
    url: 'xxx',
    method: 'post',
    headers: { 'Content-Type': 'multipart/form-data' },
    responseType: 'blob',
    data: data,
    onUploadProgress//添加进度事件
  })
}
//定义进度事件
const uploadEvent = (progressEvent) => {
    //计算进度
          this.progressPercent = Number(
            ((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
          );
        };
// 接口上传文件传入进度事件
        await apiImport(formData, uploadEvent)
// 文件上传接口,添加onUploadProgress获取上传进度信息
export function apiImport (data,onUploadProgress) {
  return request({
    url: 'xxx',
    method: 'post',
    headers: { 'Content-Type': 'multipart/form-data' },
    responseType: 'blob',
    data: data,
    onUploadProgress//添加进度事件
  })
}
//定义进度事件
const uploadEvent = (progressEvent) => {
    //计算进度
          this.progressPercent = Number(
            ((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
          );
        };
// 接口上传文件传入进度事件
        await apiImport(formData, uploadEvent)

vue2全局注册扩展api组件

js
import Vue from 'vue'
import Custom from '@/components/outWorkerComp/Custom.vue'
const CustomComponent = Vue.extend(Custome)
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {

  Vue.prototype.$showCustom = function () {
    var instance = new CustomComponent().$mount()
    document.body.appendChild(instance.$el) // 添加到 body 标签之中
  }
}
export default MyPlugin
//main.js中use
import Vue from 'vue'
import Custom from '@/components/outWorkerComp/Custom.vue'
const CustomComponent = Vue.extend(Custome)
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {

  Vue.prototype.$showCustom = function () {
    var instance = new CustomComponent().$mount()
    document.body.appendChild(instance.$el) // 添加到 body 标签之中
  }
}
export default MyPlugin
//main.js中use

绝对路径/相对路径判断

js
//判断绝对路径
export function isAbsoluteURL(url: string): boolean {
  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}
//相对路径拼接基地址
export function combineURL(baseURL: string, relativeURL?: string): string {
  return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
}
//判断绝对路径
export function isAbsoluteURL(url: string): boolean {
  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}
//相对路径拼接基地址
export function combineURL(baseURL: string, relativeURL?: string): string {
  return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
}

去除字符串中的HTML标签

js
const pureStr = str.replace(/<[^<]*>/g,'')
const pureStr = str.replace(/<[^<]*>/g,'')

读取剪切板上的excel数据

js
document.addEventListener('paste', event => {
  // event里的clipboardData对象
  const html = event.clipboardData.getData('text/html');
  const excelDocument = new DOMParser().parseFromString(html,'text/html');
  // 加载所有的行
  const tableDom = excelDocument.querySelectorAll('table tr')
  const tableData = []
  for(const trNode of tableDom){
      const trData = []
      for(const tdNode of trNode.children){
          trData.push(tdNode.innerText)
      }
      tableData.push(trData)
  }
  console.log(tableData)//嵌套表格数据结果
})
document.addEventListener('paste', event => {
  // event里的clipboardData对象
  const html = event.clipboardData.getData('text/html');
  const excelDocument = new DOMParser().parseFromString(html,'text/html');
  // 加载所有的行
  const tableDom = excelDocument.querySelectorAll('table tr')
  const tableData = []
  for(const trNode of tableDom){
      const trData = []
      for(const tdNode of trNode.children){
          trData.push(tdNode.innerText)
      }
      tableData.push(trData)
  }
  console.log(tableData)//嵌套表格数据结果
})

过滤树节点菜单数据

js
function filterTreeData(
  keyWord: string,
  data: FileMenu,
  attribute: string = 'name'
) {
  return data.filter((item: any) => {
    const hasChildren = item.children && item.children.length > 0
    const isMatch = item[attribute].includes(keyWord)
    if (hasChildren) {
      item.children = filterTreeData(keyWord, item.children)
      return item.children.length > 0
    } else {
      return isMatch
    }
  })
}
function filterTreeData(
  keyWord: string,
  data: FileMenu,
  attribute: string = 'name'
) {
  return data.filter((item: any) => {
    const hasChildren = item.children && item.children.length > 0
    const isMatch = item[attribute].includes(keyWord)
    if (hasChildren) {
      item.children = filterTreeData(keyWord, item.children)
      return item.children.length > 0
    } else {
      return isMatch
    }
  })
}

h5判断ios和Android

js
 // 判断iOS 
function isIOS() {
  const u = navigator.userAgent
  return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
}

 // 判断android 
export const isAndroid = ()=>{
    let u = navigator.userAgent;
    let android = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; 
    return android
}
 // 判断iOS 
function isIOS() {
  const u = navigator.userAgent
  return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
}

 // 判断android 
export const isAndroid = ()=>{
    let u = navigator.userAgent;
    let android = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; 
    return android
}

一维数组转二位数组

js
const arrTrans = (num, arr) => {
  const iconsArr = []; // 声明外层数组
  arr.forEach((item, index) => {
    const page = Math.floor(index / num); // 计算该元素应为第几个元素组内
    if (!iconsArr[page]) { // 判断要加入的分组数组是否存在
      iconsArr[page] = [];
    }
    iconsArr[page].push(item);
  });
  return iconsArr;
}
const arrTrans = (num, arr) => {
  const iconsArr = []; // 声明外层数组
  arr.forEach((item, index) => {
    const page = Math.floor(index / num); // 计算该元素应为第几个元素组内
    if (!iconsArr[page]) { // 判断要加入的分组数组是否存在
      iconsArr[page] = [];
    }
    iconsArr[page].push(item);
  });
  return iconsArr;
}

批量压缩下载文件

js
/
 * 获取文件
 * @param url
 * @returns {Promise<any>}
 */
const getBlob = (url) => {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()

    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response)
      }
    }

    xhr.send()
  })
}

/
 * 批量打包zip包下载
 * @param urlArr Array [{url: 下载文件的路径, fileName: 下载文件名称}]
 * @param filename zip文件名
 */
export const download = (urlArr, filename = '打包下载') => {
  if (!urlArr.length > 0) return
  const zip = new JSZip()
  const cache = {}
  const promises = []
  urlArr.forEach((item) => {
    const promise = getBlob(item.url).then((data) => { // 下载文件, 并存成ArrayBuffer对象
      zip.file(item.fileName, data, { binary: true }) // 逐个添加文件
      cache[item.fileName] = data
    })
    promises.push(promise)
  })

  Promise.all(promises).then(() => {
    zip.generateAsync({ type: 'blob' }).then((content) => { // 生成二进制流
      FileSaver.saveAs(content, `${filename}.zip`) // 利用file-saver保存文件
    })
  })
}
/
 * 获取文件
 * @param url
 * @returns {Promise<any>}
 */
const getBlob = (url) => {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()

    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response)
      }
    }

    xhr.send()
  })
}

/
 * 批量打包zip包下载
 * @param urlArr Array [{url: 下载文件的路径, fileName: 下载文件名称}]
 * @param filename zip文件名
 */
export const download = (urlArr, filename = '打包下载') => {
  if (!urlArr.length > 0) return
  const zip = new JSZip()
  const cache = {}
  const promises = []
  urlArr.forEach((item) => {
    const promise = getBlob(item.url).then((data) => { // 下载文件, 并存成ArrayBuffer对象
      zip.file(item.fileName, data, { binary: true }) // 逐个添加文件
      cache[item.fileName] = data
    })
    promises.push(promise)
  })

  Promise.all(promises).then(() => {
    zip.generateAsync({ type: 'blob' }).then((content) => { // 生成二进制流
      FileSaver.saveAs(content, `${filename}.zip`) // 利用file-saver保存文件
    })
  })
}

动态解构赋值

需要使用:号来重命名变量

ts
const children = 'childrenList'

  const {[children]:child,...rest}=item
  console.log(child)

  const {channelArticles: { [channelId]: channelArticle }} = useAppSelector((state) => state.homeSlice)
  console.log(channelArticle)
const children = 'childrenList'

  const {[children]:child,...rest}=item
  console.log(child)

  const {channelArticles: { [channelId]: channelArticle }} = useAppSelector((state) => state.homeSlice)
  console.log(channelArticle)

防抖函数

ts
/**
 * 函数防抖
 * @param fn 执行函数
 * @param delay 执行延迟
 * @returns 带防抖功能的函数
 */
export function useDebounce<T = any>(this: any, fn: (e?: T) => void, delay: number): (e?: T) => void {
  let timer: number
  return (...args) => {
    timer && window.clearTimeout(timer)
    timer = window.setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}
/**
 * 函数防抖
 * @param fn 执行函数
 * @param delay 执行延迟
 * @returns 带防抖功能的函数
 */
export function useDebounce<T = any>(this: any, fn: (e?: T) => void, delay: number): (e?: T) => void {
  let timer: number
  return (...args) => {
    timer && window.clearTimeout(timer)
    timer = window.setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

努力成为全干型人才