tools.md

Object 序列化

export const paramString = (obj: any) => {
  return Object.keys(obj).map(key => (`${key}=${obj[key]||''}`)).join('&')
}

web 本地存储修复

Storage.prototype.getItemFix = key => {
  let value = null
  try {
    value = JSON.parse(localStorage.getItem(key))
  } catch (error) {
    value = localStorage.getItem(key)
  }
  if (['null', 'undefined'].includes(value)) return null
  return value
}
自动注册异步组件
// 统一注册全局异步组件(业务组件 和 ui组件)
export default (Vue, options) => {
    // require.context 中 mode 属性,default:async,默认会打包到app.js文件里;
    // 可以使用 lazy 设置为 chunk module
    const context = require.context('@/components/', false, /^p|v|ui+\.vue$/, 'lazy');
    // 遍历获取组件对象,注册组件
    context.keys().map(fileName => {
        const componentname = fileName.replace("./", "").replace(".vue", "")
        // 注意: 这里直接使用 ()=> import('path') 和 require 按需方式都不会生效
        Vue.component(componentname, () => context(fileName))
    })
}

图片懒加载的原理主要是判断当前图片是否到了可视区域这一核心逻辑实现的

getBoundingClientRect()
拿到所有的图片 dom 。
遍历每个图片判断当前图片(element.getBoundingClientRect().top)是否到了可视区范围(document.body.clientHeight)内。
如果到了就设置图片的 src 属性。
绑定 window 的 scroll 事件,对其进行节流事件监听。
IntersectionObserver
目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"

var io = new IntersectionObserver(callback, option)
// 开始观察
io.observe(document.getElementById('example'))
// 停止观察
io.unobserve(element)
.target:被观察的目标元素,是一个 DOM 节点对象
.isIntersecting: 目标是否可见
let observer = new IntersectionObserver((entries, self) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      let img = entry.target
      let src = img.dataset.src
      if (src) {
        img.src = src
        img.removeAttribute('data-src')
      }
      // 解除观察
      self.unobserve(entry.target)
    }
  })
}, config)

otehr js知识

// mixins.js 类。函数的装饰器
export function mixins(...list) {
  return function (target) {
    Object.assign(target.prototype, ...list)
  }
}

// main.js
import { mixins } from './mixins.js'

const Foo = {
  foo() { console.log('foo') }
};

@mixins(Foo)
class MyClass {}

let obj = new MyClass();
obj.foo() // 'foo'

// js (~-1 == 0)
// 把一维数组切割成每个元素包含指定长度二维数组
    splitArray(a, size = 3) {
      const arr = []
      for (let i = 0; i < a.length; i += size) {
        arr.push(a.slice(i, i + size))
      }
      console.log(arr)
    }
// vuecli
config.optimization.runtimeChunk('single') // 更好的缓存app.js
config.optimization.minimize(true) // 代码压缩

/////////////////
input type=file accept=""时,
可解决ios/iphone上不能选择除图片外的其他文件问题。

// 快速清空数组
const ay = [1,2]
ay.length = 0

// 文件上传FormData
function upload(e = {}) {
    const formData = new FormData()
    const oFile = e.file // 文件对象
    formData.append('file', oFile)
    uploadImg(formData, {
      fileName: oFile.name,
      fileType: oFile.type
    })
}

export function debounce(cb, delay) {
  let timer = null
  return function (...args) {
    clearTimeout(timer)
    timer = setTimeout(() => {
      cb.apply(this, args)
    }, delay)
  }
}
export function throttle(cb, delay) {
  let timer = null
  return () => {
    if (timer) return false
    timer = setTimeout(e => {
      timer = null
      clearTimeout(timer)
      cb && cb()
    }, delay)
  }
}
export function sum(n) {
  if (n < 2) return n
  return sum(n - 1) + n
}
export function tick(cb, delay = 1000 * 10) {
  cb.timer = setInterval(() => {
    cb && cb()
  }, delay)
  return cb.timer
}
export const touchEv = {
  onTouchStart(cb) {
    this.longClick = 0 // 初始化
    this.timeOutEvent = setTimeout(() => {
      this.longClick = 1 // 长按标志位
      // 此处为长按事件逻辑
      console.log('长按事件')
      cb && cb()
    }, 500) // 一般为300毫秒;浏览器默认时间
  },
  onTouchEnd() {
    clearTimeout(this.timeOutEvent) // 清除计时器
    if (this.timeOutEvent !== 0 && this.longClick === 0) {
      // 判断是否非长按事件
      // 此处为点击事件
      console.log('点击事件')
    }
  }
}

export function deepCopy(data) {
  const t = Object.prototype.toString.call(data)
  let o = {}
  const isObj = t.includes('Array') || t.includes('Object')
  console.log(o)
  if (isObj) {
    o = t.includes('Array') ? [] : {}
  } else {
    return data
  }

  if (isObj) {
    for (const i in data) {
      o[i] = deepCopy(data[i])
      console.log(o)
    }
  }
  return o
}
JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里属于IT工程师。