fetch 封装

# fetch 封装

/*
组件使用
let get =(data)=>{
  console.log(data)
}
let headleChange = ctx.$Api("w", "post", get);
let click = ()=>{
  headleChange(data) // 默认值是 ''
}
*/
export default function(url = '', type, callback) {
    let timer = null
    let options = {}
    let options2 = {}
    return function(data = {}) {
        // 如果有这个定时器的话就清除,如果没有就向下执行
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
            // 判断传过来的参数是对 object 还是 string
            if (typeof data === 'string') {
                // 更改对象中的属性值
                Object.defineProperties(options2, {
                    headers: {
                        value: {
                            "Content-Type": "application/x-www-form-urlencoded"
                        }
                    },
                    body: {
                        value: data
                    }
                })
            }
            options = {
                method: type,
                // 设置请求头,注意:如果不设置请求头的话,post请求的时候,后端拿不到请求参数
                headers: {
                    // 如果设置这样的请求头body参数这样写:如:body:"?key=123&age=18"
                    // "Content-Type": "application/x-www-form-urlencoded", 
                    "Content-Type": "application/json"
                },
                body: JSON.stringify(data)
            }
            // 获取token
            let token = window.localStorage.getItem('token')
            let Authorization = 'Authorization'
            if (token) {
                // 判断是否有token,如果有就添加到options对象中headers对象中
                options.headers[Authorization] = token
            }
            // 遍历循环进行对象合并
            for (let key in options) {
                if (options.hasOwnProperty(key) && options2.hasOwnProperty(key)) {
                    options[key] = options2[key]
                }
            }
            // 如果是get请求的话删除 options对象中的body属性
            if (type === 'get') {
                delete options.body // 删除options中的body属性
            }

            let loaddinfDiv = document.createElement('div') // 创建了一个元素
            let appDiv = document.getElementById('app') // 获取id为app 的元素
            // 添加样式
            loaddinfDiv.style = `width:100%;height:100%;background-color:#4AAF33;border-radius:4px;box-shadow:0 0 3px #ddd inset;text-align:center;z-index:100;color:#fff`
            loaddinfDiv.innerText = '页面加载中,请等待 . . .' // 添加文本
            loaddinfDiv.id = 'loadding' // 添加一个id
            let body = document.body // 获取body标签
            appDiv.style.display = 'none' // 把id为app 元素隐藏
            body.appendChild(loaddinfDiv) // 往body中添加元素

            // 发起请求
            fetch(`http://localhost:666/${url}`, options)
                .then((response) => {
                    return response.json()
                }) // 设置响应值
                .then(async (res) => {
                    /*
                    建议:如果是做后台管理系统的话,使用sessionStorage来做本地缓存
                    */
                    await callback(res)
                    if (res.token) {
                        window.localStorage.setItem('token', res.token)
                    }
                    // 请求完数据之后删除创建的元素,并把body元素显示
                    body.removeChild(loaddinfDiv)
                    appDiv.style.display = 'block'
                }).catch(async () => {
                    await callback('服务器错误,请稍后重试')
                })
            // 解决常占内存问题
            timer = null
        }, 500);
    }
}