web 记录 axios tools
axios处理和封装
import axios from 'axios'
const service = axios.create({
  baseURL: '/',
  timeout: 15000,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache',
    Pragma: 'no-cache',
    Accept: '*/*'
  }
})
service.interceptors.request.use(config => config)
service.interceptors.response.use(response => {
  const { data } = response
  if (data.code === 401) { // 重新去登录
  }
  if (data.code !== 200) { // 错误统一处理
    alert(data.msg)
    return Promise.reject(data)
  }
  return data
}, error => {
  return Promise.reject(error)
})

export default {
  post(params) {
    return service({
      method: 'post',
      ...params
    })
  },
  get(params) {
    return service({ method: 'get', params: params.data, ...params })
  },
  download(params) {
    return service({ method: params.method || 'post', ...params, responseType: 'arraybuffer' })
  },
  upload(url, data) {
    return server({
      method: 'post',
      url,
      data,
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  }
}
.npmrc
registry=https://pkg.vankeservice.com/repository/npm-public/
export const exportFile = (obj) => {
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(new Blob([obj.data]), obj.name);
        return
    }
    const url = window.URL.createObjectURL(new Blob([obj.data]))
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.setAttribute('download', obj.name)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(link.href)
}
// 滚动加载更多数据处理
const scrollDom = document.querySelector('.people-list .el-table__body-wrapper');
scrollDom.onscroll = debounce(() => {
    const {
        scrollHeight,
        scrollTop,
        clientHeight
    } = scrollDom;
    // 滚动总高度, 距离滚动起点距离, 可视高度
    const distance = scrollHeight - scrollTop - clientHeight;
    if (distance < 5 && this.gridData.length < this.total) {
        this.loading = true;
        this.getTableData();
    }
});
this.$once("hook:beforeDestroy", () => {
    scrollDom.onscroll = null;
})
// axios文件上传
import axios from 'axios'
// 添加请求头 上传文件时  数据不用经过任何处理
update(e) { // 上传照片
    let self = this
    let file = e.target.files[0]
    /* eslint-disable no-undef */
    let param = new FormData() // 创建form对象
    param.append('file', file) // 通过append向form对象添加数据
    param.append('chunk', '0') // 添加form表单中其他数据
    console.log(param.get('file')) // FormData私有类对象,访问不到,可以通过get判断值是否传进去
    let config = {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    }
    // 添加请求头
    axios.post('http://172.19.26.60:8081/rest/user/headurl', param, config)
        .then(res => {
            if (res.data.code === 0) {
                self.ImgUrl = res.data.data
            }
            console.log(res.data)
        })
}
// axios
axios.get('http://localhost:3000/users').then(res => {
    console.log(res)
}).catch(() => {}).then(res => { // 总是会执行
    console.log(res)
})
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')) {
            if ((/^[0-9]+$/.test(time))) {
                // support "1548221490638"
                time = parseInt(time)
            } else {
                // support safari
                // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
                time = time.replace(new RegExp(/-/gm), '/')
            }
        }

        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
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
    if (('' + time).length === 10) {
        time = parseInt(time) * 1000
    } else {
        time = +time
    }
    const d = new Date(time)
    const now = Date.now()

    const diff = (now - d) / 1000

    if (diff < 30) {
        return '刚刚'
    } else if (diff < 3600) {
        // less 1 hour
        return Math.ceil(diff / 60) + '分钟前'
    } else if (diff < 3600 * 24) {
        return Math.ceil(diff / 3600) + '小时前'
    } else if (diff < 3600 * 24 * 2) {
        return '1天前'
    }
    if (option) {
        return parseTime(time, option)
    } else {
        return (
            d.getMonth() +
            1 +
            '月' +
            d.getDate() +
            '日' +
            d.getHours() +
            '时' +
            d.getMinutes() +
            '分'
        )
    }
}

function Clone(obj) { // 深拷贝
    for (var i in obj) {
        this[i] = typeof obj[i] === 'object' ? new Clone(obj[i]) : obj[i]
    }
}

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 (let i = 0; i < data.length; i++) {
        //     o.push(deepCopy(data[i]));
        // }
        for (let i in data) {
            o[i] = deepCopy(data[i]);
            console.log(o)
        }
    }
    // else if (t === 'object') {
    //        for (let i in data) {
    //            o[i] = deepCopy(data[i]);
    //            console.log(o)
    //        }
    //    }
    return o;
}

// h5 web worker
// webwork.js
let i=0;
function timedCount() {
    i=i+1;
    postMessage(i);
    setTimeout(timedCount,500);
}

timedCount();
// end
let w;

function startWorker() {
    if (typeof(Worker) !== "undefined") {
        if (typeof(w) == "undefined") {
            w = new Worker("demo_workers.js");
        }
        w.onmessage = function(event) {
            document.getElementById("result").innerHTML = event.data;
        };
    } else {
        document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";
    }
}

function stopWorker() {
    w.terminate();
    w = undefined;
}

///////////////////////////////////
// 自动注册模板
const requireComponent = require.context('../components', false, /\.vue$/)
const requireYuli = require.context('../components/views', false, /\.vue$/)
const cmps = {}

function dealCmps(load) {
    load.keys().forEach(component => {
        const cmp = load(component).default
        // cmp.name // component.replace(/^\.\//, '').replace(/\.\w+$/, '')
        const cmpName = component.split('.vue')[0].split('/').slice(-1).join('')
        cmps[cmpName] = cmp
        console.log(cmp.__file.split('.vue')[0].split('/').slice(-1).join(''))
    })
}
// dealCmps(requireComponent)
// dealCmps(requireYuli)
// 高德mouseTool插件
mouseTool.on('draw', function(e) {
    overlays.push(e.obj)
    console.log(e.obj.getOptions()) // 获取绘制对象的相关属性
    // console.log(e.obj.aE[0][0])
})
// 创建新分支并推送
// git checkout -b dev
// git push --set-upstream origin dev // git push origin dev:dev
// 合并某个文件到当前分支
// git checkout xxxx(分支名) xxxx(文件名)
// git revert 【方法二撤销merge时提交的commit的版本号]

let longClick = 0
let timer = null
function onTouchStart() {
  longClick = 0
  timer = setTimeout(() => {
    longClick = 1
    const vConsole = new VConsole();
    Vue.use(vConsole);
  }, 3500)
}

function onTouchEnd() {
  clearTimeout(timer)
  if (timer !== 0 && longClick === 0) {}
}

document.body.addEventListener('touchstart', onTouchStart)
document.body.addEventListener('touchend', onTouchEnd)

/////// .editorconfig{}
// root = true

// [*]
// charset = utf-8
// indent_style = space
// indent_size = 2
// end_of_line = lf
// insert_final_newline = true
// trim_trailing_whitespace = true

///// less url 拼接
// .bgimg(@url){
//   background-image: url('~@/assets/@{url}');
//   background-size: 100%;
// }

// websocket vue
let webSocketsService = {}

webSocketsService.install = function (Vue, options) {
  let ws = new WebSocket(options.url)
  let reconnectInterval = options.reconnectInterval || 1000

  Vue.prototype.$webSocketsConnect = () => {
    ws = new WebSocket(options.url)

    ws.onopen = () => {
      // Restart reconnect interval
      reconnectInterval = options.reconnectInterval || 1000
    }

    ws.onmessage = (event) => {
      // New message from the backend - use JSON.parse(event.data)
      handleNotification(event)
    }

    ws.onclose = (event) => {
      if (event) {
        // Event.code 1000 is our normal close event
        if (event.code !== 1000) {
          let maxReconnectInterval = options.maxReconnectInterval || 3000
          setTimeout(() => {
            if (reconnectInterval < maxReconnectInterval) {
              // Reconnect interval can't be > x seconds
              reconnectInterval += 1000
            }
            Vue.prototype.$webSocketsConnect()
          }, reconnectInterval)
        }
      }
    }

    ws.onerror = (error) => {
      console.log(error)
      ws.close()
    }
  }

  Vue.prototype.$webSocketsDisconnect = () => {
    // Our custom disconnect event
    ws.close()
  }

  Vue.prototype.$webSocketsSend = (data) => {
    // Send data to the backend - use JSON.stringify(data)
    ws.send(JSON.stringify(data))
  }

  /*
    Here we write our custom functions to not make a mess in one function
  */
  function handleNotification (params) {
    console.log(params)
    options.store.dispatch('notifications/setNotifications', params.data)
  }
}

export default webSocketsService

// 格式化数字
function trimExtraChar(value, char, regExp) {
  const index = value.indexOf(char);
  let prefix = '';

  if (index === -1) {
    return value;
  }

  if (char === '-' && index !== 0) {
    return value.slice(0, index);
  }

  if (char === '.' && value.match(/^(\.|-\.)/)) {
    prefix = index ? '-0' : '0';
  }

  return (
    prefix + value.slice(0, index + 1) + value.slice(index).replace(regExp, '')
  );
}

export function formatNumber(
  value,
  allowDot = true,
  allowMinus = true
) {
  if (allowDot) {
    value = trimExtraChar(value, '.', /\./g);
  } else {
    value = value.split('.')[0];
  }

  if (allowMinus) {
    value = trimExtraChar(value, '-', /-/g);
  } else {
    value = value.replace(/-/, '');
  }

  const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g;

  return value.replace(regExp, '');
}

// 20. getScrollPosition:返回当前的滚动位置
// 默认参数为window ,pageXOffset(pageYOffset)为第一选择,没有则用scrollLeft(scrollTop)

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});

getScrollPosition(); // {x: 0, y: 200}
// 22. escapeHTML:转义HTML
**// 当然是用来防XSS攻击啦。**

const escapeHTML = str =>
  str.replace(
    /[&<>'"]/g,
    tag =>
      ({
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        "'": '&#39;',
        '"': '&quot;'
      }[tag] || tag)
  );
export const sort = (arr, type = 1) => {
  return arr.sort((a, b) => {
      switch (type) {
          case 1:
            return a - b; // 升序
          case 2:
            return b - a; // 降序
          case 3:
            return Math.random() - 0.5; // 随机
          default:
            return arr;
      }
  }
  export const trim = (str, type) => {
      type = type || 1
      switch (type) {
          case 1:
            return str.replace(/\s+/g, "");
          case 2:
            return str.replace(/(^\s*)|(\s*$)/g, "");
          case 3:
            return str.replace(/(^\s*)/g, "");
          case 4:
            return str.replace(/(\s*$)/g, "");
          default:
            return str;
      }
  }
  var Main = {
      data() {
        return {
          active: null
        };
      },
      methods: {
        move (e) {
          const dom = e.target
          const parent = document.querySelector('#app');
          e = e || window.event
          let xDown = e.clientX
          let yDown = e.clientY
          let leftDown = dom.offsetLeft
          let topDown = dom.offsetTop
          document.onmousemove = (e) => {
            e = e || window.event
            let xMove = e.clientX
            let yMove = e.clientY
            let _x = xMove - xDown
            let _y = yMove - yDown
            console.log(leftDown, topDown)
            console.log(e)
            let oLeft = leftDown + _x;
            let oTop = topDown + _y;
            if (oLeft <= 0) {
              oLeft = 0
            }
            if (oTop <= 0) {
              oTop = 0
            }
            if (oLeft >= parent.clientWidth - 200) {
              oLeft = parent.clientWidth - 200
            }
            if (oTop >= parent.clientHeight - 200) {
              oTop = parent.clientHeight - 200
            }
            dom.style.left = oLeft + 'px'
            dom.style.top = oTop + 'px'
          }
          document.onmouseup = function() {
            this.onmouseup = null
            this.onmousemove = null
          }
        }
      }
    }
  // var Ctor = Vue.extend(Main)
  // new Ctor().$mount('#app')
  methods: {
      touchstart(ev) {
        this.startX = ev.touches[0].pageX
        this.startY = ev.touches[0].pageY
      },
      getSlideDirection(startX, startY, endX, endY) {
        const dy = startY - endY
        let result = 0
        if (dy > 15) {
          //向上滑动
          result = 1
        } else if (dy < -15) {
          //向下滑动
          result = 2
        } else {
          result = 0
        }
        return result
      },
      touchmove(ev) {
        const endX = ev.changedTouches[0].pageX
        const endY = ev.changedTouches[0].pageY
        this.endY = endY
        const direction = this.getSlideDirection(
          this.startX,
          this.startY,
          endX,
          endY
        )
        const dom = this.$refs.box
        this.cardDom = dom
        const top = window
          .getComputedStyle(dom, null)
          .getPropertyValue('top')
        const intPx = parseInt(top)
        // dom.style.cssText = 'overflow-x:hidden;overflow-y:hidden'
        switch (direction) {
          case 0:
            // console.log('无操作')
            break
          case 1:
            // 向上
            // console.log('上')
            if (intPx === 356 && this.$route.name !== 'index') { // 中间
              dom.style.top = '45px'
            }
            if (intPx >= 498) {
              dom.style.top = '356px'
            }
            break
          case 2:
            // 向下
            // console.log('下', -380)
            if (intPx === 356) {
              dom.style.top = '70%'
              if (this.$route.name === 'index') {
                dom.style.top = '75%'
              }
            }
            if (intPx === 45) {
              dom.style.top = '356px'
            }
            break
        }
      },
      touchend() {
        // const box = document.querySelector('.info-wrap')
        // const s = this.startY - this.endY
        // if (s > 0) {
        //   this.ds = -s
        // } else {
        //   this.ds = Math.abs(s)
        // }
        // const dom = this.$refs.box
        // if (parseInt(dom.style.bottom) >= 111 && box.clientHeight > dom.clientHeight) {
        //   box.style.transform = `translateY(${this.ds}px)`
        // }
      }
    },

    // 将 click 事件直接绑定到目标元素(即 .target)上
    // 将目标元素换成 <a> 或者 button 等可点击的元素
    // 将 click 事件委托到非 document 或 body 的父级元素上
    // 给目标元素加一条样式规则 cursor: pointer;
JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里属于IT工程师。