配置 .gitignore
This commit is contained in:
parent
6e0361deef
commit
fb1bd80d5a
|
|
@ -0,0 +1,24 @@
|
|||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
**/*.log
|
||||
|
||||
tests/**/coverage/
|
||||
tests/e2e/reports
|
||||
selenium-debug.log
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.local
|
||||
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
pnpm-lock.yaml
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": true,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf",
|
||||
"useTabs": false,
|
||||
"trailingComma": "none",
|
||||
"bracketSameLine": false,
|
||||
"htmlWhitespaceSensitivity": "ignore",
|
||||
"vueIndentScriptAndStyle": false,
|
||||
"singleAttributePerLine": false,
|
||||
"importStatement": "none"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,2 +0,0 @@
|
|||
/// <reference path="./uni-app/index.d.ts" />
|
||||
/// <reference path="./html5plus/plus.d.ts" />
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"_args": [
|
||||
[
|
||||
"@dcloudio/types@2.6.12",
|
||||
"C:\\Users\\Administrator\\Desktop\\yn"
|
||||
]
|
||||
],
|
||||
"_from": "@dcloudio/types@2.6.12",
|
||||
"_id": "@dcloudio/types@2.6.12",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-mrCMwcINy1IFjU9VUqLeWBkj404yWs5paLDttBcA+eqUjanuUQbBcTVPqlrGgkyzLXDcV2oDDZRSNxNpXi4kMQ==",
|
||||
"_location": "/@dcloudio/types",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "@dcloudio/types@2.6.12",
|
||||
"name": "@dcloudio/types",
|
||||
"escapedName": "@dcloudio%2ftypes",
|
||||
"scope": "@dcloudio",
|
||||
"rawSpec": "2.6.12",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.6.12"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/luch-request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/@dcloudio/types/-/types-2.6.12.tgz",
|
||||
"_spec": "2.6.12",
|
||||
"_where": "C:\\Users\\Administrator\\Desktop\\yn",
|
||||
"author": {
|
||||
"name": "fxy060608"
|
||||
},
|
||||
"description": "uni-app types",
|
||||
"devDependencies": {
|
||||
"vue": "^2.6.10"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"name": "@dcloudio/types",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"typings": "index.d.ts",
|
||||
"version": "2.6.12"
|
||||
}
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
declare namespace App {
|
||||
interface ReferrerInfo {
|
||||
/**
|
||||
* 来源小程序或公众号或App的 appId
|
||||
*
|
||||
* 以下场景支持返回 referrerInfo.appId:
|
||||
* - 1020(公众号 profile 页相关小程序列表): appId
|
||||
* - 1035(公众号自定义菜单):来源公众号 appId
|
||||
* - 1036(App 分享消息卡片):来源应用 appId
|
||||
* - 1037(小程序打开小程序):来源小程序 appId
|
||||
* - 1038(从另一个小程序返回):来源小程序 appId
|
||||
* - 1043(公众号模板消息):来源公众号 appId
|
||||
*/
|
||||
appId: string;
|
||||
/**
|
||||
* 来源小程序传过来的数据,scene=1037或1038时支持
|
||||
*/
|
||||
extraData?: any;
|
||||
}
|
||||
|
||||
interface LaunchShowOption {
|
||||
/**
|
||||
* 打开小程序的路径
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
* 打开小程序的query
|
||||
*/
|
||||
query: AnyObject;
|
||||
/**
|
||||
* 打开小程序的场景值
|
||||
* - 1001: 发现栏小程序主入口,「最近使用」列表(基础库2.2.4版本起包含「我的小程序」列表)
|
||||
* - 1005: 顶部搜索框的搜索结果页
|
||||
* - 1006: 发现栏小程序主入口搜索框的搜索结果页
|
||||
* - 1007: 单人聊天会话中的小程序消息卡片
|
||||
* - 1008: 群聊会话中的小程序消息卡片
|
||||
* - 1011: 扫描二维码
|
||||
* - 1012: 长按图片识别二维码
|
||||
* - 1013: 手机相册选取二维码
|
||||
* - 1014: 小程序模板消息
|
||||
* - 1017: 前往体验版的入口页
|
||||
* - 1019: 微信钱包
|
||||
* - 1020: 公众号 profile 页相关小程序列表
|
||||
* - 1022: 聊天顶部置顶小程序入口
|
||||
* - 1023: 安卓系统桌面图标
|
||||
* - 1024: 小程序 profile 页
|
||||
* - 1025: 扫描一维码
|
||||
* - 1026: 附近小程序列表
|
||||
* - 1027: 顶部搜索框搜索结果页「使用过的小程序」列表
|
||||
* - 1028: 我的卡包
|
||||
* - 1029: 卡券详情页
|
||||
* - 1030: 自动化测试下打开小程序
|
||||
* - 1031: 长按图片识别一维码
|
||||
* - 1032: 手机相册选取一维码
|
||||
* - 1034: 微信支付完成页
|
||||
* - 1035: 公众号自定义菜单
|
||||
* - 1036: App 分享消息卡片
|
||||
* - 1037: 小程序打开小程序
|
||||
* - 1038: 从另一个小程序返回
|
||||
* - 1039: 摇电视
|
||||
* - 1042: 添加好友搜索框的搜索结果页
|
||||
* - 1043: 公众号模板消息
|
||||
* - 1044: 带 shareTicket 的小程序消息卡片
|
||||
* - 1045: 朋友圈广告
|
||||
* - 1046: 朋友圈广告详情页
|
||||
* - 1047: 扫描小程序码
|
||||
* - 1048: 长按图片识别小程序码
|
||||
* - 1049: 手机相册选取小程序码
|
||||
* - 1052: 卡券的适用门店列表
|
||||
* - 1053: 搜一搜的结果页
|
||||
* - 1054: 顶部搜索框小程序快捷入口
|
||||
* - 1056: 音乐播放器菜单
|
||||
* - 1057: 钱包中的银行卡详情页
|
||||
* - 1058: 公众号文章
|
||||
* - 1059: 体验版小程序绑定邀请页
|
||||
* - 1064: 微信连Wi-Fi状态栏
|
||||
* - 1067: 公众号文章广告
|
||||
* - 1068: 附近小程序列表广告
|
||||
* - 1069: 移动应用
|
||||
* - 1071: 钱包中的银行卡列表页
|
||||
* - 1072: 二维码收款页面
|
||||
* - 1073: 客服消息列表下发的小程序消息卡片
|
||||
* - 1074: 公众号会话下发的小程序消息卡片
|
||||
* - 1077: 摇周边
|
||||
* - 1078: 连Wi-Fi成功页
|
||||
* - 1079: 微信游戏中心
|
||||
* - 1081: 客服消息下发的文字链
|
||||
* - 1082: 公众号会话下发的文字链
|
||||
* - 1084: 朋友圈广告原生页
|
||||
* - 1089: 微信聊天主界面下拉,「最近使用」栏(基础库2.2.4版本起包含「我的小程序」栏)
|
||||
* - 1090: 长按小程序右上角菜单唤出最近使用历史
|
||||
* - 1091: 公众号文章商品卡片
|
||||
* - 1092: 城市服务入口
|
||||
* - 1095: 小程序广告组件
|
||||
* - 1096: 聊天记录
|
||||
* - 1097: 微信支付签约页
|
||||
* - 1099: 页面内嵌插件
|
||||
* - 1102: 公众号 profile 页服务预览
|
||||
* - 1103: 发现栏小程序主入口,「我的小程序」列表(基础库2.2.4版本起废弃)
|
||||
* - 1104: 微信聊天主界面下拉,「我的小程序」栏(基础库2.2.4版本起废弃)
|
||||
*/
|
||||
scene: number;
|
||||
/**
|
||||
* 打开小程序的场景值
|
||||
*/
|
||||
shareTicket: string;
|
||||
/**
|
||||
* 当场景为由从另一个小程序或公众号或App打开时,返回此字段
|
||||
*/
|
||||
referrerInfo?: ReferrerInfo;
|
||||
}
|
||||
|
||||
interface PageNotFoundOption {
|
||||
/**
|
||||
* 不存在页面的路径
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
* 打开不存在页面的 query
|
||||
*/
|
||||
query: AnyObject;
|
||||
/**
|
||||
* 是否本次启动的首个页面(例如从分享等入口进来,首个页面是开发者配置的分享页面)
|
||||
*/
|
||||
isEntryPage: boolean;
|
||||
}
|
||||
|
||||
interface AppInstance<T extends AnyObject = {}> {
|
||||
/**
|
||||
* 全局对象
|
||||
*/
|
||||
globalData?: AnyObject;
|
||||
/**
|
||||
* 生命周期回调 监听应用初始化
|
||||
*
|
||||
* 应用初始化完成时触发,全局只触发一次。
|
||||
*/
|
||||
onLaunch?(options?: LaunchShowOption): void;
|
||||
/**
|
||||
* 生命周期回调 监听应用显示
|
||||
*
|
||||
* 应用启动,或从后台进入前台显示时触发
|
||||
*/
|
||||
onShow?(options?: LaunchShowOption): void;
|
||||
/**
|
||||
* 生命周期回调 监听应用隐藏
|
||||
*
|
||||
* 应用从前台进入后台时触发
|
||||
*/
|
||||
onHide?(): void;
|
||||
/**
|
||||
* 错误监听函数
|
||||
* 小程序发生脚本错误或 API 调用报错时触发
|
||||
* @param error 错误信息,包含堆栈
|
||||
*/
|
||||
onError?(error: string): void;
|
||||
/**
|
||||
* 页面不存在监听函数
|
||||
*
|
||||
* 应用要打开的页面不存在时触发,会带上页面信息回调该函数
|
||||
*
|
||||
* **注意:**
|
||||
* 1. 如果开发者没有添加 `onPageNotFound` 监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面。
|
||||
* 2. 如果 `onPageNotFound` 回调中又重定向到另一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,并且不再回调 `onPageNotFound`。
|
||||
*/
|
||||
onPageNotFound?(options: PageNotFoundOption): void;
|
||||
/**
|
||||
* 未处理的 Promise 拒绝事件监听函数
|
||||
*/
|
||||
onUnhandledRejection?(options: UniApp.OnUnhandledRejectionCallbackResult): void;
|
||||
/**
|
||||
* 监听系统主题变化
|
||||
*/
|
||||
onThemeChange?(options: UniApp.OnThemeChangeCallbackResult): void;
|
||||
/**
|
||||
* 监听 nvue 页面消息
|
||||
*
|
||||
* nvue 页面使用 `uni.postMessage` 发送消息时触发
|
||||
*/
|
||||
onUniNViewMessage?(options: AnyObject): void;
|
||||
}
|
||||
|
||||
type AppConstructor = <T extends AnyObject & AppInstance>(
|
||||
options: AppInstance<T> & T,
|
||||
) => void;
|
||||
|
||||
interface GetAppOption {
|
||||
/**
|
||||
* 在 `App` 未定义时返回默认实现。当App被调用时,默认实现中定义的属性会被覆盖合并到App中。一般用于独立分包
|
||||
*/
|
||||
allowDefault: boolean;
|
||||
}
|
||||
|
||||
type GetApp = <T extends AnyObject>(opts?: GetAppOption) => AppInstance<T> & T;
|
||||
}
|
||||
|
||||
declare const getApp: App.GetApp;
|
||||
|
||||
declare const createApp: any;
|
||||
declare const createPage: any;
|
||||
declare const createComponent: any;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
interface AnyObject {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
type KVInfer<T> = { [K in keyof T]: T[K] };
|
||||
|
||||
type Void<T> = T | undefined | null;
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/// <reference path="./app.d.ts" />
|
||||
/// <reference path="./common.d.ts" />
|
||||
/// <reference path="./page.d.ts" />
|
||||
/// <reference path="./uni.d.ts" />
|
||||
/// <reference path="./cloud.d.ts" />
|
||||
/// <reference path="./vue.d.ts" />
|
||||
/// <reference path="../html5plus/plus.d.ts" />
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
declare namespace Page {
|
||||
interface CustomShareContent {
|
||||
/**
|
||||
* 转发标题。默认值:当前应用名称
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 转发路径,必须是以 / 开头的完整路径。默认值:当前页面 path
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* 自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4,默认值:使用默认截图
|
||||
*/
|
||||
imageUrl?: string;
|
||||
}
|
||||
|
||||
interface ShareTimelineContent {
|
||||
/**
|
||||
* 自定义标题。默认值:当前小程序名称
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 自定义页面路径中携带的参数
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* 自定义图片路径,可以是本地文件或者网络图片。支持 PNG 及 JPG,显示图片长宽比是 1:1。
|
||||
*/
|
||||
imageUrl?: string;
|
||||
}
|
||||
|
||||
interface PageScrollOption {
|
||||
/**
|
||||
* 页面在垂直方向已滚动的距离(单位 px)
|
||||
*/
|
||||
scrollTop: number;
|
||||
}
|
||||
|
||||
interface ShareAppMessageOption {
|
||||
/**
|
||||
* 转发事件来源。
|
||||
* 可选值:
|
||||
* - `button`:页面内转发按钮;
|
||||
* - `menu`:右上角转发菜单。
|
||||
*/
|
||||
from: "button" | "menu";
|
||||
/**
|
||||
* 如果 `from` 值是 `button`,则 `target` 是触发这次转发事件的 `button`,否则为 `undefined`
|
||||
*/
|
||||
target: any;
|
||||
/**
|
||||
* 页面中包含 `<web-view>` 组件时,返回当前 `<web-view>` 的 url
|
||||
*/
|
||||
webViewUrl?: string;
|
||||
}
|
||||
|
||||
interface AddToFavoritesOption {
|
||||
/**
|
||||
* 页面中包含 `<web-view>` 组件时,返回当前 `<web-view>` 的 url
|
||||
*/
|
||||
webviewUrl: string
|
||||
}
|
||||
|
||||
interface CustomFavoritesContent {
|
||||
/**
|
||||
* 自定义标题,默认值:页面标题或账号名称
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 自定义 query 字段
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* 自定义图片,显示图片长宽比为 1:1
|
||||
*/
|
||||
imageUrl?: string;
|
||||
}
|
||||
|
||||
interface TabItemTapOption {
|
||||
/**
|
||||
* 被点击 tabItem 的序号,从0开始
|
||||
*/
|
||||
index: string;
|
||||
/**
|
||||
* 被点击 tabItem 的页面路径
|
||||
*/
|
||||
pagePath: string;
|
||||
/**
|
||||
* 被点击 tabItem 的按钮文字
|
||||
*/
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface NavigationBarButtonTapOption {
|
||||
/**
|
||||
* 原生标题栏按钮数组的下标
|
||||
*/
|
||||
index: string;
|
||||
}
|
||||
|
||||
interface BackPressOption {
|
||||
/**
|
||||
* - backbutton 顶部导航栏左边的返回按钮或 Android 实体返回键
|
||||
* - navigateBack 返回 API,即 uni.navigateBack()
|
||||
*/
|
||||
from: 'backbutton' | 'navigateBack';
|
||||
}
|
||||
|
||||
interface NavigationBarSearchInputEvent {
|
||||
/**
|
||||
* 搜索输入框输入内容
|
||||
*/
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface PageInstanceBaseProps<D extends AnyObject = any> {
|
||||
/**
|
||||
* 到当前页面的路径,类型为 `String`
|
||||
*/
|
||||
route?: string;
|
||||
}
|
||||
|
||||
interface PageInstance<D extends AnyObject = any, T extends AnyObject = any> extends PageInstanceBaseProps<D> {
|
||||
/**
|
||||
* 生命周期回调 监听页面初始化
|
||||
*
|
||||
* 页面初始化时触发。一个页面只会调用一次,可以在 onInit 的参数中获取打开当前页面路径中的参数。
|
||||
* @param query 打开当前页面路径中的参数
|
||||
*/
|
||||
onInit?(query?: AnyObject): void;
|
||||
/**
|
||||
* 生命周期回调 监听页面加载
|
||||
*
|
||||
* 页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
|
||||
* @param query 打开当前页面路径中的参数
|
||||
*/
|
||||
onLoad?(query?: AnyObject): void;
|
||||
/**
|
||||
* 生命周期回调 监听页面显示
|
||||
*
|
||||
* 页面显示/切入前台时触发。
|
||||
*/
|
||||
onShow?(): void;
|
||||
/**
|
||||
* 生命周期回调 监听页面初次渲染完成
|
||||
*
|
||||
* 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
|
||||
*/
|
||||
onReady?(): void;
|
||||
/**
|
||||
* 生命周期回调 监听页面隐藏
|
||||
*
|
||||
* 页面隐藏/切入后台时触发。 如 `navigateTo` 或底部 `tab` 切换到其他页面,应用切入后台等。
|
||||
*/
|
||||
onHide?(): void;
|
||||
/**
|
||||
* 生命周期回调 监听页面卸载
|
||||
*
|
||||
* 页面卸载时触发。如 `redirectTo` 或 `navigateBack` 到其他页面时。
|
||||
*/
|
||||
onUnload?(): void;
|
||||
/**
|
||||
* 监听用户下拉动作
|
||||
* - 需要在 `pages.json` 的页面配置中开启 `enablePullDownRefresh` 。
|
||||
* - 可以通过 `uni.startPullDownRefresh` 触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
|
||||
* - 当处理完数据刷新后,`uni.stopPullDownRefresh` 可以停止当前页面的下拉刷新。
|
||||
*/
|
||||
onPullDownRefresh?(): void;
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
* - 可以在 `pages.json` 的页面配置中设置触发距离 `onReachBottomDistance` 。
|
||||
* - 在触发距离内滑动期间,本事件只会被触发一次。
|
||||
*/
|
||||
onReachBottom?(): void;
|
||||
/**
|
||||
* 用户点击右上角转发
|
||||
*
|
||||
* 监听用户点击页面内转发按钮(`<button>` 组件 `open-type="share"`)或右上角菜单“转发”按钮的行为,并自定义转发内容。
|
||||
* @param options 分享发起来源参数
|
||||
* @return 转发内容
|
||||
*/
|
||||
onShareAppMessage?(options: ShareAppMessageOption): CustomShareContent;
|
||||
/**
|
||||
* 用户点击右上角转发到朋友圈
|
||||
*
|
||||
* 监听右上角菜单“分享到朋友圈”按钮的行为,并自定义发享内容。
|
||||
*/
|
||||
onShareTimeline?(): ShareTimelineContent;
|
||||
/**
|
||||
* 用户点击右上角收藏
|
||||
*
|
||||
* 监听用户点击右上角菜单“收藏”按钮的行为,并自定义收藏内容。
|
||||
*/
|
||||
onAddToFavorites?(options: AddToFavoritesOption): CustomFavoritesContent;
|
||||
/**
|
||||
* 页面滚动触发事件的处理函数
|
||||
*
|
||||
* 监听用户滑动页面事件。
|
||||
* @param options 页面滚动参数
|
||||
*/
|
||||
onPageScroll?(options: PageScrollOption): void;
|
||||
/**
|
||||
* 页面尺寸改变时触发
|
||||
* @param options 页面滚动参数
|
||||
*/
|
||||
onResize?(options: PageScrollOption): void;
|
||||
/**
|
||||
* 当前是 tab 页时,点击 tab 时触发
|
||||
* @param options tab 点击参数
|
||||
*/
|
||||
onTabItemTap?(options: TabItemTapOption): void;
|
||||
/**
|
||||
* 监听原生标题栏按钮点击事件
|
||||
* @param options tab 点击参数
|
||||
*/
|
||||
onNavigationBarButtonTap?(options: NavigationBarButtonTapOption): void;
|
||||
/**
|
||||
* 监听页面返回
|
||||
* @param options tab 点击参数
|
||||
* @return 返回 `true` 时阻止页面返回
|
||||
*/
|
||||
onBackPress?(options: BackPressOption): any;
|
||||
/**
|
||||
* 监听原生标题栏搜索输入框输入内容变化事件
|
||||
*/
|
||||
onNavigationBarSearchInputChanged?(event: NavigationBarSearchInputEvent): void;
|
||||
/**
|
||||
* 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。
|
||||
*/
|
||||
onNavigationBarSearchInputConfirmed?(event: NavigationBarSearchInputEvent): void;
|
||||
/**
|
||||
* 监听原生标题栏搜索输入框点击事件
|
||||
*/
|
||||
onNavigationBarSearchInputClicked?(): void;
|
||||
}
|
||||
|
||||
type PageConstructor = <T extends AnyObject & PageInstance>(
|
||||
options: PageInstance<AnyObject, T> & T,
|
||||
) => void;
|
||||
|
||||
type GetCurrentPages = <T extends AnyObject = {}>() => Array<PageInstance<AnyObject, T> & T>;
|
||||
}
|
||||
|
||||
declare const getCurrentPages: Page.GetCurrentPages;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,11 +0,0 @@
|
|||
import Vue from "vue";
|
||||
|
||||
declare module "vue/types/options" {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
interface ComponentOptions<V extends Vue> extends Hooks {
|
||||
/**
|
||||
* 组件类型
|
||||
*/
|
||||
mpType?: string;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) [2022] [luch]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
## [3.1.0](https://github.com/lei-mu/luch-request/compare/3.0.8...3.1.0) (2023-05-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 更新请求新配置项。新增‘是否尝试将响应数据json化’配置项。 ([68344a1](https://github.com/lei-mu/luch-request/commit/68344a1d9dcbf586d4a0aff37d02aa0bb27ff45c)), closes [#113](https://github.com/lei-mu/luch-request/issues/113)
|
||||
* 增加`version` 属性,获取插件版本号 ([40403d2](https://github.com/lei-mu/luch-request/commit/40403d2ef57dead0f577a384ac686cc7dcc772da))
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.0.8](https://github.com/lei-mu/luch-request/compare/3.0.7...3.0.8) (2022-08-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* `put` 方法增加快手小程序和京东小程序的支持 ([7e15dff](https://github.com/lei-mu/luch-request/commit/7e15dff0ac343ccbd6a298c7c9ae8ef0e2148eb9))
|
||||
* 参考axio源代码 添加支持paramsSerializer。 ([cae1043](https://github.com/lei-mu/luch-request/commit/cae10430dc7222d85e0cadb13512898d66998547))
|
||||
* 返回数据增加`rawData`,保留返回的原始数据 ([3924b7c](https://github.com/lei-mu/luch-request/commit/3924b7c3ea444526be436a31f9e7d5623749580b))
|
||||
* 局部请求配置支持baseURL ([df2d98f](https://github.com/lei-mu/luch-request/commit/df2d98fc063f356ffd525158e9cd47d7eb24f68f))
|
||||
|
||||
|
||||
|
||||
|
||||
## 3.0.7 (2021-09-04)
|
||||
|
||||
1. Bug Fix: 修复通过 `Request.config` 设置全局参数,多个实例`config`存在共同引用bug
|
||||
|
||||
|
||||
## 3.0.6 (2021-05-10)
|
||||
|
||||
1. New Feature: APP端 增加`responseType`配置项
|
||||
|
||||
## 3.0.5 (2021-01-10)
|
||||
### Features
|
||||
|
||||
* [重要] APP不再支持`CONNECT`、`HEAD`、`TRACE`请求方式。[uni.request](https://uniapp.dcloud.io/api/request/request)
|
||||
* [重要]全局默认`timeout`由`30000`ms,改为`60000`ms
|
||||
* [重要]增加`index.d.ts`文件支持。感谢`Mr_Mao`的支持。github:`https://github.com/TuiMao233`
|
||||
* [重要]网络请求相关接口 uni.request、uni.uploadFile、uni.downloadFile 支持 timeout 参数。
|
||||
* [重要]返回结果response 增加`fullPath`参数。
|
||||
|
||||
## 3.0.4 (2020-07-05)
|
||||
|
||||
1. New Feature: request 方法增加 ` firstIpv4 `配置项
|
||||
1. New Feature: 增加 ` middleware `通用请求方法
|
||||
|
||||
## 3.0.3 (2020-06-16)
|
||||
|
||||
1. Bug Fix: 修复` params ` 选项对数组格式化错误bug
|
||||
|
||||
## 3.0.2 (2020-06-04)
|
||||
|
||||
1. Bug Fix: 修复文件上传和request 配置缺少字段bug
|
||||
|
||||
## 3.0.1 (2020-06-02)
|
||||
|
||||
1. Bug Fix: 请求方式都为` GET `的bug
|
||||
|
||||
## 3.0.0 (2020-06-01)
|
||||
|
||||
1. New Feature: 支持多拦截器
|
||||
1. New Feature: 支持局部配置自定义验证器
|
||||
|
||||
## 2.0.1 (2020-05-01)
|
||||
|
||||
1. Bug Fix: 修复多实例全局配置共用问题
|
||||
|
||||
## 2.0.0 (2020-04-24)
|
||||
|
||||
1. New Feature: 增加 request ` withCredentials `选项(仅h5端支持)
|
||||
1. New Feature: h5端 upload 增加 ` files ` ` file `选项。[uni.uploadFile](https://uniapp.dcloud.io/api/request/network-file?id=uploadfile "uni.uploadFile")
|
||||
1. Enhancement: ` params ` 选项参数格式化方法使用axios 格式化方法
|
||||
1. Bug Fix: 对upload 返回data 为空字符串的情况容错
|
||||
1. Change: 修改header与全局合并方式。当前:header = Object.assign(全局,局部)
|
||||
|
||||
## 0.0.0 (2019-05)
|
||||
|
||||
1. luch-request created
|
||||
|
||||
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
{
|
||||
"_args": [
|
||||
[
|
||||
"luch-request@3.1.1",
|
||||
"C:\\Users\\Administrator\\Desktop\\yn"
|
||||
]
|
||||
],
|
||||
"_from": "luch-request@3.1.1",
|
||||
"_id": "luch-request@3.1.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-p7+mlcEtgRcd0OfXC4XZbyiwSr1XgCeqNT7LlVUjnk7InYl/8d5Rk7BUqAYNA2WRafI1wRIUQWRWZRpeUwWR0w==",
|
||||
"_location": "/luch-request",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "luch-request@3.1.1",
|
||||
"name": "luch-request",
|
||||
"escapedName": "luch-request",
|
||||
"rawSpec": "3.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/luch-request/-/luch-request-3.1.1.tgz",
|
||||
"_spec": "3.1.1",
|
||||
"_where": "C:\\Users\\Administrator\\Desktop\\yn",
|
||||
"author": {
|
||||
"name": "luch"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/lei-mu/luch-request/issues"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
},
|
||||
"ghooks": {
|
||||
"commit-msg": "validate-commit-msg"
|
||||
},
|
||||
"validate-commit-msg": {
|
||||
"types": [
|
||||
"feat",
|
||||
"fix",
|
||||
"docs",
|
||||
"style",
|
||||
"refactor",
|
||||
"perf",
|
||||
"test",
|
||||
"build",
|
||||
"ci",
|
||||
"chore",
|
||||
"revert"
|
||||
],
|
||||
"scope": {
|
||||
"required": false,
|
||||
"allowed": [
|
||||
"*"
|
||||
],
|
||||
"validate": false,
|
||||
"multiple": false
|
||||
},
|
||||
"warnOnFail": false,
|
||||
"maxSubjectLength": 100,
|
||||
"subjectPattern": ".+",
|
||||
"subjectPatternErrorMsg": "subject does not match subject pattern!",
|
||||
"helpMessage": "",
|
||||
"autoFix": false
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/types": "^2.0.16"
|
||||
},
|
||||
"description": "基于Promise实现uni-app request 请求插件",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/plugin-transform-arrow-functions": "^7.8.3",
|
||||
"@babel/preset-env": "^7.9.5",
|
||||
"@vuepress/plugin-active-header-links": "^1.5.0",
|
||||
"@vuepress/plugin-pwa": "^1.5.2",
|
||||
"archiver": "^4.0.1",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"cz-conventional-changelog": "^3.2.0",
|
||||
"eslint": "^6.8.0",
|
||||
"grunt": "^1.1.0",
|
||||
"grunt-babel": "^8.0.0",
|
||||
"load-grunt-tasks": "^5.1.0",
|
||||
"node-zip": "^1.1.1",
|
||||
"rollup": "^2.66.1",
|
||||
"rollup-plugin-babel": "^4.4.0",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-copy": "^3.3.0",
|
||||
"rollup-plugin-eslint": "^7.0.0",
|
||||
"rollup-plugin-json": "^4.0.0",
|
||||
"rollup-plugin-live-server": "^1.0.3",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-uglify": "^6.0.4",
|
||||
"rollup-plugin-zip": "^1.0.0",
|
||||
"validate-commit-msg": "^2.14.0",
|
||||
"vuepress": "^1.4.1"
|
||||
},
|
||||
"engines": {},
|
||||
"homepage": "https://www.quanzhan.co/luch-request/",
|
||||
"keywords": [
|
||||
"uni-app",
|
||||
"request",
|
||||
"Promise",
|
||||
"luch",
|
||||
"luch-request"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "src/lib/luch-request.js",
|
||||
"name": "luch-request",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lei-mu/luch-request.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rimraf DCloud && rollup -c --environment NODE_ENV:production",
|
||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0",
|
||||
"dev": "rollup -c",
|
||||
"docs": "vuepress dev docs",
|
||||
"docs:build": "vuepress build docs",
|
||||
"pub": "npm publish && cnpm sync luch-request",
|
||||
"pub:alpha": "npm publish --tag=alpha && cnpm sync luch-request",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"watch": "rollup -c -w",
|
||||
"zipD": "node node/zipDCloudPlugin.js && node node/zipDCloudDemo.js"
|
||||
},
|
||||
"version": "3.1.1"
|
||||
}
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
# luch-request
|
||||
|
||||
[](https://www.npmjs.com/package/luch-request "npm")
|
||||
[](https://www.npmjs.com/package/luch-request "npm")
|
||||
[](https://github.com/lei-mu/luch-request "github")
|
||||
[](https://github.com/lei-mu/luch-request "github stars")
|
||||
[](https://github.com/lei-mu/luch-request "github forks")
|
||||
|
||||
- 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
|
||||
- 支持全局挂载
|
||||
- 支持多个全局配置实例
|
||||
- 支持自定义验证器
|
||||
- 支持文件上传/下载
|
||||
- 支持task 操作
|
||||
- 支持自定义参数
|
||||
- 支持多拦截器
|
||||
- 对参数的处理比uni.request 更强
|
||||
|
||||
安装
|
||||
------------
|
||||
###### 使用npm
|
||||
|
||||
``` javascript
|
||||
npm install luch-request -S
|
||||
```
|
||||
使用npm前阅读[快速上手](https://www.quanzhan.co/luch-request/handbook/#npm "快速上手")
|
||||
|
||||
|
||||
###### github
|
||||
|
||||
[github](https://github.com/lei-mu/luch-request "github")
|
||||
安装依赖后 ` npm run build ` ,使用DCloud/luch-request 文件夹即可
|
||||
|
||||
|
||||
###### DCloud插件市场:
|
||||
|
||||
[DCloud插件市场](https://ext.dcloud.net.cn/plugin?id=392 "DCloud插件市场")
|
||||
|
||||
Example
|
||||
------------
|
||||
创建实例
|
||||
|
||||
``` javascript
|
||||
import Request from '@/utils/luch-request/index.js' // 下载的插件
|
||||
// import Request from 'luch-request' // 使用npm
|
||||
|
||||
const http = new Request();
|
||||
```
|
||||
|
||||
执行` GET `请求
|
||||
|
||||
``` javascript
|
||||
http.get('/user/login', {params: {userName: 'name', password: '123456'}}).then(res => {
|
||||
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
// 局部修改配置,局部配置优先级高于全局配置
|
||||
http.get('/user/login', {
|
||||
params: {userName: 'name', password: '123456'}, /* 会加在url上 */
|
||||
header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */
|
||||
dataType: 'json',
|
||||
// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
|
||||
custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token
|
||||
// #ifndef MP-ALIPAY
|
||||
responseType: 'text',
|
||||
// #endif
|
||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
||||
timeout: 60000, // H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
sslVerify: true, // 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+)
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
withCredentials: false, // 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
|
||||
// #endif
|
||||
// 返回当前请求的task, options。请勿在此处修改options。非必填
|
||||
getTask: (task, options) => {
|
||||
// setTimeout(() => {
|
||||
// task.abort()
|
||||
// }, 500)
|
||||
},
|
||||
// 自定义验证器。statusCode必存在。非必填
|
||||
validateStatus: function validateStatus(statusCode) {
|
||||
return statusCode >= 200 && statusCode < 300
|
||||
},
|
||||
// forcedJSONParsing: true, // 是否尝试将响应数据json化,默认为true。如果失败则返回原数据
|
||||
}).then(res => {
|
||||
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
```
|
||||
执行` POST `请求
|
||||
|
||||
``` javascript
|
||||
http.post('/user/login', {userName: 'name', password: '123456'} ).then(res => {
|
||||
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
// 局部修改配置,局部配置优先级高于全局配置
|
||||
http.post('/user/login', {userName: 'name', password: '123456'}, {
|
||||
params: {}, /* 会加在url上 */
|
||||
header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */
|
||||
dataType: 'json',
|
||||
// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
|
||||
custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token
|
||||
// #ifndef MP-ALIPAY
|
||||
responseType: 'text',
|
||||
// #endif
|
||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
||||
timeout: 60000, // H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
sslVerify: true, // 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+)
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
withCredentials: false, // 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
|
||||
// #endif
|
||||
// 返回当前请求的task, options。请勿在此处修改options。非必填
|
||||
getTask: (task, options) => {
|
||||
// setTimeout(() => {
|
||||
// task.abort()
|
||||
// }, 500)
|
||||
},
|
||||
// 自定义验证器。statusCode必存在。非必填
|
||||
validateStatus: function validateStatus(statusCode) {
|
||||
return statusCode >= 200 && statusCode < 300
|
||||
}
|
||||
}).then(res => {
|
||||
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
```
|
||||
执行` upload `请求
|
||||
|
||||
``` javascript
|
||||
http.upload('api/upload/img', {
|
||||
params: {}, /* 会加在url上 */
|
||||
// #ifdef APP-PLUS || H5
|
||||
files: [], // 需要上传的文件列表。使用 files 时,filePath 和 name 不生效。App、H5( 2.6.15+)
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
fileType: 'image/video/audio', // 仅支付宝小程序,且必填。
|
||||
// #endif
|
||||
filePath: '', // 要上传文件资源的路径。
|
||||
// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
|
||||
custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token
|
||||
name: 'file', // 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
|
||||
// #ifdef H5 || APP-PLUS
|
||||
timeout: 60000, // H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)
|
||||
// #endif
|
||||
header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */
|
||||
formData: {}, // HTTP 请求中其他额外的 form data
|
||||
// 返回当前请求的task, options。请勿在此处修改options。非必填
|
||||
getTask: (task, options) => {
|
||||
// task.onProgressUpdate((res) => {
|
||||
// console.log('上传进度' + res.progress);
|
||||
// console.log('已经上传的数据长度' + res.totalBytesSent);
|
||||
// console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
|
||||
//
|
||||
// // 测试条件,取消上传任务。
|
||||
// if (res.progress > 50) {
|
||||
// uploadTask.abort();
|
||||
// }
|
||||
// });
|
||||
},
|
||||
// 是否尝试将响应数据json化。boolean 或者一个包含include的对象。非必填。默认true。include为数组,包含需要json化的method
|
||||
// forcedJSONParsing: {include: ['UPLOAD', 'DOWNLOAD']}
|
||||
}).then(res => {
|
||||
// 返回的res.data 已经进行JSON.parse
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
```
|
||||
|
||||
luch-request Guide
|
||||
------------
|
||||
[luch-request 官网地址](https://www.quanzhan.co/luch-request/ "luch-request 官网地址")
|
||||
<br>
|
||||
[github](https://github.com/lei-mu/luch-request "github")
|
||||
|
||||
友情链接
|
||||
------------
|
||||
#### vue-admin-beautiful
|
||||
**vue-admin-beautiful** ——<a href="https://github.com/chuzhixin/vue-admin-beautiful" target="_blank">企业级、通用型中后台前端解决方案(基于vue/cli 4 最新版,同时支持电脑,手机,平板)</a>
|
||||
|
||||
**vue-admin-beautiful** ——<a href="http://beautiful.panm.cn/vue-admin-beautiful/#/index" target="_blank">在线演示</a>
|
||||
|
||||
#### uView
|
||||
<a href="https://uviewui.com" target="_blank">uView 文档</a> ——超棒的移动跨端框架,文档详细,上手容易
|
||||
|
||||
常见问题
|
||||
------------
|
||||
1. 为什么会请求两次?
|
||||
- 总有些小白问这些很那啥的问题,有两种可能,一种是‘post三次握手’,还有一种可能是`本地访问接口时跨域请求,所以浏览器会先发一个option 去预测能否成功,然后再发一个真正的请求`(自己观察请求头,Request Method,百度简单请求)。
|
||||
2. 如何跨域?
|
||||
- 问的人不少,可以先百度了解一下。<a href="https://ask.dcloud.net.cn/article/35267" target="_blank">如何跨域</a>
|
||||
3. post 怎么传不了数组的参数啊?
|
||||
- <a href="https://uniapp.dcloud.io/api/request/request" target="_blank">uni-request</a> <br>
|
||||
可以点击看一下uni-request 的api 文档,data支持的文件类型只有<code>Object/String/ArrayBuffer</code>这个真跟我没啥关系 0.0
|
||||
4. TypeError: undefined is not an object (evaluating 'this.$http.get')
|
||||
- 不知道为啥问的人这么多?太基础了,百度学习一下 export default 和export,头大。
|
||||
- `import { http } from '@/utils/luch-request/index.js'`
|
||||
5. 什么参数需要在` setConfig ` 设置?什么参数需要在` request ` 拦截器设置?
|
||||
- ` setConfig ` 适用于设置一些静态的/默认的参数;比如header 里的一些默认值、默认全局参数(全局请求配置)。` token ` 并不适合在这里设置。
|
||||
- ` interceptors.request ` 拦截器适用范围较广,但我仍然建议把一些静态的东西放在 ` setConfig ` 里。拦截器会在每次请求调用,而 ` setConfig ` 仅在调用时修改一遍。
|
||||
|
||||
tip
|
||||
------------
|
||||
- nvue 不支持全局挂载
|
||||
- 当前的hbuilderx 版本号:beat-3.0.4 alpha-3.0.4
|
||||
- 推荐使用下载插件的方式使用。如果本插件完全满足你的需求可直接使用 ` npm `安装
|
||||
- license: MIT
|
||||
|
||||
|
||||
issue
|
||||
------------
|
||||
- DCloud: 有任何问题或者建议可以=> <a href="https://ask.dcloud.net.cn/question/74922" target="_blank">issue提交</a>,先给个五星好评QAQ!!
|
||||
- github: [Issues](https://github.com/lei-mu/luch-request/issues "Issues")
|
||||
|
||||
|
||||
作者想说
|
||||
------------
|
||||
- 写代码很容易,为了让你们看懂写文档真的很lei 0.0
|
||||
- 最近发现有插件与我雷同,当初接触uni-app 就发现插件市场虽然有封装的不错的request库,但是都没有对多全局配置做处理,都是通过修改源码的方式配置。我首先推出通过class类,并仿照axios的api实现request请求库,并起名‘仿axios封装request网络请求库,支持拦截器全局配置’。他们虽然修改了部分代码,但是功能与性能并没有优化,反而使代码很冗余。希望能推出新的功能,和性能更加强悍的请求库。(2019-05)
|
||||
- 任何形式的‘参考’、‘借鉴’,请标明作者
|
||||
```javascript
|
||||
<a href="https://ext.dcloud.net.cn/plugin?id=392">luch-request</a>
|
||||
```
|
||||
- 关于问问题
|
||||
1. 首先请善于利用搜索引擎,不管百度,还是Google,遇到问题请先自己尝试解决。自己尝试过无法解决,再问。
|
||||
2. 不要问类似为什么我的xx无法使用这种问题。请仔细阅读文档,检查代码,或者说明运行环境,把相关代码贴至评论或者发送至我的邮箱,还可以点击上面的issue提交,在里面提问,可能我在里面已经回答了。
|
||||
3. 我的代码如果真的出现bug,或者你有好的建议、需求,可以提issue,我看到后会立即解决
|
||||
|
||||
- 如何问问题
|
||||
1. 问问题之前请换位思考,如果自己要解决这个问题,需要哪些信息
|
||||
2. 仔细阅读文档,检查代码
|
||||
3. 说明运行环境,比如:app端 ios、android 版本号、手机机型、普遍现象还是个别现象(越详细越好)
|
||||
4. 发出代码片段或者截图至邮箱(很重要)
|
||||
5. 或者可以在上方的'issue提交' 里发出详细的问题描述
|
||||
6. 以上都觉得解决不了你的问题,可以加QQ:`370306150`
|
||||
|
||||
个人网站
|
||||
------------
|
||||
- 欢迎大家都来踩一踩<a href="https://www.quanzhan.co/" target="_blank">luch的博客</a> 0.0
|
||||
|
||||
|
||||
|
||||
|
||||
土豪赞赏
|
||||
------------
|
||||
[](https://www.quanzhan.co/luch-request/acknowledgement/#前言 "wechat 打赏")
|
||||
[](https://www.quanzhan.co/luch-request/acknowledgement/#前言 "支付宝 打赏")
|
||||
|
||||
[打赏事宜具体说明](https://www.quanzhan.co/luch-request/acknowledgement/#前言 "打赏事宜具体说明")
|
||||
|
||||
|
||||
###### 您的鼓励是我更新的动力
|
||||
|
||||
#### 创作不易,五星好评你懂得!
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
import buildURL from '../helpers/buildURL'
|
||||
import buildFullPath from '../core/buildFullPath'
|
||||
import settle from '../core/settle'
|
||||
import {isUndefined} from "../utils"
|
||||
|
||||
/**
|
||||
* 返回可选值存在的配置
|
||||
* @param {Array} keys - 可选值数组
|
||||
* @param {Object} config2 - 配置
|
||||
* @return {{}} - 存在的配置项
|
||||
*/
|
||||
const mergeKeys = (keys, config2) => {
|
||||
let config = {}
|
||||
keys.forEach(prop => {
|
||||
if (!isUndefined(config2[prop])) {
|
||||
config[prop] = config2[prop]
|
||||
}
|
||||
})
|
||||
return config
|
||||
}
|
||||
export default (config) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer)
|
||||
const _config = {
|
||||
url: fullPath,
|
||||
header: config.header,
|
||||
complete: (response) => {
|
||||
config.fullPath = fullPath
|
||||
response.config = config
|
||||
response.rawData = response.data
|
||||
try {
|
||||
let jsonParseHandle = false
|
||||
const forcedJSONParsingType = typeof config.forcedJSONParsing
|
||||
if (forcedJSONParsingType === 'boolean') {
|
||||
jsonParseHandle = config.forcedJSONParsing
|
||||
} else if (forcedJSONParsingType === 'object') {
|
||||
const includesMethod = config.forcedJSONParsing.include || []
|
||||
jsonParseHandle = includesMethod.includes(config.method)
|
||||
}
|
||||
|
||||
// 对可能字符串不是json 的情况容错
|
||||
if (jsonParseHandle && typeof response.data === 'string') {
|
||||
response.data = JSON.parse(response.data)
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {
|
||||
}
|
||||
settle(resolve, reject, response)
|
||||
}
|
||||
}
|
||||
let requestTask
|
||||
if (config.method === 'UPLOAD') {
|
||||
delete _config.header['content-type']
|
||||
delete _config.header['Content-Type']
|
||||
let otherConfig = {
|
||||
// #ifdef MP-ALIPAY
|
||||
fileType: config.fileType,
|
||||
// #endif
|
||||
filePath: config.filePath,
|
||||
name: config.name
|
||||
}
|
||||
const optionalKeys = [
|
||||
// #ifdef APP-PLUS || H5
|
||||
'files',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
'file',
|
||||
// #endif
|
||||
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||
'timeout',
|
||||
// #endif
|
||||
'formData'
|
||||
]
|
||||
requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)})
|
||||
} else if (config.method === 'DOWNLOAD') {
|
||||
const optionalKeys = [
|
||||
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||
'timeout',
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
'filePath',
|
||||
// #endif
|
||||
]
|
||||
requestTask = uni.downloadFile({..._config, ...mergeKeys(optionalKeys, config)})
|
||||
} else {
|
||||
const optionalKeys = [
|
||||
'data',
|
||||
'method',
|
||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
||||
'timeout',
|
||||
// #endif
|
||||
'dataType',
|
||||
// #ifndef MP-ALIPAY
|
||||
'responseType',
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
'sslVerify',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
'withCredentials',
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
'firstIpv4',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
'enableHttp2',
|
||||
'enableQuic',
|
||||
// #endif
|
||||
// #ifdef MP-TOUTIAO || MP-WEIXIN
|
||||
'enableCache',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
'enableHttpDNS',
|
||||
'httpDNSServiceId',
|
||||
'enableChunked',
|
||||
'forceCellularNetwork',
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
'enableCookie',
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU
|
||||
'cloudCache',
|
||||
'defer'
|
||||
// #endif
|
||||
]
|
||||
requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)})
|
||||
}
|
||||
if (config.getTask) {
|
||||
config.getTask(requestTask, config)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
|
||||
function InterceptorManager() {
|
||||
this.handlers = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new interceptor to the stack
|
||||
*
|
||||
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
||||
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
||||
*
|
||||
* @return {Number} An ID used to remove interceptor later
|
||||
*/
|
||||
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
|
||||
this.handlers.push({
|
||||
fulfilled: fulfilled,
|
||||
rejected: rejected
|
||||
})
|
||||
return this.handlers.length - 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an interceptor from the stack
|
||||
*
|
||||
* @param {Number} id The ID that was returned by `use`
|
||||
*/
|
||||
InterceptorManager.prototype.eject = function eject(id) {
|
||||
if (this.handlers[id]) {
|
||||
this.handlers[id] = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over all the registered interceptors
|
||||
*
|
||||
* This method is particularly useful for skipping over any
|
||||
* interceptors that may have become `null` calling `eject`.
|
||||
*
|
||||
* @param {Function} fn The function to call for each interceptor
|
||||
*/
|
||||
InterceptorManager.prototype.forEach = function forEach(fn) {
|
||||
this.handlers.forEach(h => {
|
||||
if (h !== null) {
|
||||
fn(h)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default InterceptorManager
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
/**
|
||||
* @Class Request
|
||||
* @description luch-request http请求插件
|
||||
* @Author lu-ch
|
||||
* @Email webwork.s@qq.com
|
||||
* 文档: https://www.quanzhan.co/luch-request/
|
||||
* github: https://github.com/lei-mu/luch-request
|
||||
* DCloud: http://ext.dcloud.net.cn/plugin?id=392
|
||||
*/
|
||||
|
||||
|
||||
import dispatchRequest from './dispatchRequest'
|
||||
import InterceptorManager from './InterceptorManager'
|
||||
import mergeConfig from './mergeConfig'
|
||||
import defaults from './defaults'
|
||||
import { isPlainObject } from '../utils'
|
||||
import clone from '../utils/clone'
|
||||
|
||||
export default class Request {
|
||||
/**
|
||||
* @param {Object} arg - 全局配置
|
||||
* @param {String} arg.baseURL - 全局根路径
|
||||
* @param {Object} arg.header - 全局header
|
||||
* @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
|
||||
* @param {String} arg.dataType = [json] - 全局默认的dataType
|
||||
* @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
|
||||
* @param {Object} arg.custom - 全局默认的自定义参数
|
||||
* @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
|
||||
* @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
|
||||
* @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
|
||||
* @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
|
||||
* @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
|
||||
*/
|
||||
constructor(arg = {}) {
|
||||
if (!isPlainObject(arg)) {
|
||||
arg = {}
|
||||
console.warn('设置全局参数必须接收一个Object')
|
||||
}
|
||||
this.config = clone({...defaults, ...arg})
|
||||
this.interceptors = {
|
||||
request: new InterceptorManager(),
|
||||
response: new InterceptorManager()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Function
|
||||
* @param {Request~setConfigCallback} f - 设置全局默认配置
|
||||
*/
|
||||
setConfig(f) {
|
||||
this.config = f(this.config)
|
||||
}
|
||||
|
||||
middleware(config) {
|
||||
config = mergeConfig(this.config, config)
|
||||
let chain = [dispatchRequest, undefined]
|
||||
let promise = Promise.resolve(config)
|
||||
|
||||
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
|
||||
chain.unshift(interceptor.fulfilled, interceptor.rejected)
|
||||
})
|
||||
|
||||
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
|
||||
chain.push(interceptor.fulfilled, interceptor.rejected)
|
||||
})
|
||||
|
||||
while (chain.length) {
|
||||
promise = promise.then(chain.shift(), chain.shift())
|
||||
}
|
||||
|
||||
return promise
|
||||
}
|
||||
|
||||
/**
|
||||
* @Function
|
||||
* @param {Object} config - 请求配置项
|
||||
* @prop {String} options.url - 请求路径
|
||||
* @prop {Object} options.data - 请求参数
|
||||
* @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
|
||||
* @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
|
||||
* @prop {Object} [options.header = config.header] - 请求header
|
||||
* @prop {Object} [options.method = config.method] - 请求方法
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
request(config = {}) {
|
||||
return this.middleware(config)
|
||||
}
|
||||
|
||||
get(url, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
method: 'GET',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
post(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'POST',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD
|
||||
put(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'PUT',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
||||
delete(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'DELETE',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef H5 || MP-WEIXIN
|
||||
connect(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'CONNECT',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef H5 || MP-WEIXIN || MP-BAIDU
|
||||
head(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'HEAD',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
||||
options(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'OPTIONS',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef H5 || MP-WEIXIN
|
||||
trace(url, data, options = {}) {
|
||||
return this.middleware({
|
||||
url,
|
||||
data,
|
||||
method: 'TRACE',
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
upload(url, config = {}) {
|
||||
config.url = url
|
||||
config.method = 'UPLOAD'
|
||||
return this.middleware(config)
|
||||
}
|
||||
|
||||
download(url, config = {}) {
|
||||
config.url = url
|
||||
config.method = 'DOWNLOAD'
|
||||
return this.middleware(config)
|
||||
}
|
||||
|
||||
get version () {
|
||||
return '3.1.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* setConfig回调
|
||||
* @return {Object} - 返回操作后的config
|
||||
* @callback Request~setConfigCallback
|
||||
* @param {Object} config - 全局默认config
|
||||
*/
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
import isAbsoluteURL from '../helpers/isAbsoluteURL'
|
||||
import combineURLs from '../helpers/combineURLs'
|
||||
|
||||
/**
|
||||
* Creates a new URL by combining the baseURL with the requestedURL,
|
||||
* only when the requestedURL is not already an absolute URL.
|
||||
* If the requestURL is absolute, this function returns the requestedURL untouched.
|
||||
*
|
||||
* @param {string} baseURL The base URL
|
||||
* @param {string} requestedURL Absolute or relative URL to combine
|
||||
* @returns {string} The combined full path
|
||||
*/
|
||||
export default function buildFullPath(baseURL, requestedURL) {
|
||||
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
||||
return combineURLs(baseURL, requestedURL)
|
||||
}
|
||||
return requestedURL
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* 默认的全局配置
|
||||
*/
|
||||
|
||||
|
||||
export default {
|
||||
baseURL: '',
|
||||
header: {},
|
||||
method: 'GET',
|
||||
dataType: 'json',
|
||||
paramsSerializer: null,
|
||||
// #ifndef MP-ALIPAY
|
||||
responseType: 'text',
|
||||
// #endif
|
||||
custom: {},
|
||||
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||
timeout: 60000,
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
sslVerify: true,
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
withCredentials: false,
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
firstIpv4: false,
|
||||
// #endif
|
||||
validateStatus: function validateStatus(status) {
|
||||
return status >= 200 && status < 300
|
||||
},
|
||||
// 是否尝试将响应数据json化
|
||||
forcedJSONParsing: true
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import adapter from '../adapters/index'
|
||||
|
||||
|
||||
export default (config) => {
|
||||
return adapter(config)
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
import {deepMerge, isUndefined} from '../utils'
|
||||
|
||||
/**
|
||||
* 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
|
||||
* @param {Array} keys - 配置项
|
||||
* @param {Object} globalsConfig - 当前的全局配置
|
||||
* @param {Object} config2 - 局部配置
|
||||
* @return {{}}
|
||||
*/
|
||||
const mergeKeys = (keys, globalsConfig, config2) => {
|
||||
let config = {}
|
||||
keys.forEach(prop => {
|
||||
if (!isUndefined(config2[prop])) {
|
||||
config[prop] = config2[prop]
|
||||
} else if (!isUndefined(globalsConfig[prop])) {
|
||||
config[prop] = globalsConfig[prop]
|
||||
}
|
||||
})
|
||||
return config
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param globalsConfig - 当前实例的全局配置
|
||||
* @param config2 - 当前的局部配置
|
||||
* @return - 合并后的配置
|
||||
*/
|
||||
export default (globalsConfig, config2 = {}) => {
|
||||
const method = config2.method || globalsConfig.method || 'GET'
|
||||
let config = {
|
||||
baseURL: config2.baseURL || globalsConfig.baseURL || '',
|
||||
method: method,
|
||||
url: config2.url || '',
|
||||
params: config2.params || {},
|
||||
custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})},
|
||||
header: deepMerge(globalsConfig.header || {}, config2.header || {})
|
||||
}
|
||||
const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer', 'forcedJSONParsing']
|
||||
config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)}
|
||||
|
||||
// eslint-disable-next-line no-empty
|
||||
if (method === 'DOWNLOAD') {
|
||||
const downloadKeys = [
|
||||
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||
'timeout',
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
'filePath',
|
||||
// #endif
|
||||
]
|
||||
config = {...config, ...mergeKeys(downloadKeys, globalsConfig, config2)}
|
||||
} else if (method === 'UPLOAD') {
|
||||
delete config.header['content-type']
|
||||
delete config.header['Content-Type']
|
||||
const uploadKeys = [
|
||||
// #ifdef APP-PLUS || H5
|
||||
'files',
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
'fileType',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
'file',
|
||||
// #endif
|
||||
'filePath',
|
||||
'name',
|
||||
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||
'timeout',
|
||||
// #endif
|
||||
'formData',
|
||||
]
|
||||
uploadKeys.forEach(prop => {
|
||||
if (!isUndefined(config2[prop])) {
|
||||
config[prop] = config2[prop]
|
||||
}
|
||||
})
|
||||
// #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
|
||||
if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
|
||||
config['timeout'] = globalsConfig['timeout']
|
||||
}
|
||||
// #endif
|
||||
} else {
|
||||
const defaultsKeys = [
|
||||
'data',
|
||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
||||
'timeout',
|
||||
// #endif
|
||||
'dataType',
|
||||
// #ifndef MP-ALIPAY
|
||||
'responseType',
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
'sslVerify',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
'withCredentials',
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
'firstIpv4',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
'enableHttp2',
|
||||
'enableQuic',
|
||||
// #endif
|
||||
// #ifdef MP-TOUTIAO || MP-WEIXIN
|
||||
'enableCache',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
'enableHttpDNS',
|
||||
'httpDNSServiceId',
|
||||
'enableChunked',
|
||||
'forceCellularNetwork',
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
'enableCookie',
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU
|
||||
'cloudCache',
|
||||
'defer'
|
||||
// #endif
|
||||
|
||||
]
|
||||
config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)}
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* Resolve or reject a Promise based on response status.
|
||||
*
|
||||
* @param {Function} resolve A function that resolves the promise.
|
||||
* @param {Function} reject A function that rejects the promise.
|
||||
* @param {object} response The response.
|
||||
*/
|
||||
export default function settle(resolve, reject, response) {
|
||||
const validateStatus = response.config.validateStatus
|
||||
const status = response.statusCode
|
||||
if (status && (!validateStatus || validateStatus(status))) {
|
||||
resolve(response)
|
||||
} else {
|
||||
reject(response)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
import * as utils from './../utils'
|
||||
|
||||
function encode(val) {
|
||||
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a URL by appending params to the end
|
||||
*
|
||||
* @param {string} url The base of the url (e.g., http://www.google.com)
|
||||
* @param {object} [params] The params to be appended
|
||||
* @returns {string} The formatted url
|
||||
*/
|
||||
export default function buildURL(url, params, paramsSerializer) {
|
||||
/*eslint no-param-reassign:0*/
|
||||
if (!params) {
|
||||
return url
|
||||
}
|
||||
|
||||
var serializedParams
|
||||
if (paramsSerializer) {
|
||||
serializedParams = paramsSerializer(params)
|
||||
} else if (utils.isURLSearchParams(params)) {
|
||||
serializedParams = params.toString()
|
||||
} else {
|
||||
var parts = []
|
||||
|
||||
utils.forEach(params, function serialize(val, key) {
|
||||
if (val === null || typeof val === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
if (utils.isArray(val)) {
|
||||
key = key + '[]'
|
||||
} else {
|
||||
val = [val]
|
||||
}
|
||||
|
||||
utils.forEach(val, function parseValue(v) {
|
||||
if (utils.isDate(v)) {
|
||||
v = v.toISOString()
|
||||
} else if (utils.isObject(v)) {
|
||||
v = JSON.stringify(v)
|
||||
}
|
||||
parts.push(encode(key) + '=' + encode(v))
|
||||
})
|
||||
})
|
||||
|
||||
serializedParams = parts.join('&')
|
||||
}
|
||||
|
||||
if (serializedParams) {
|
||||
var hashmarkIndex = url.indexOf('#')
|
||||
if (hashmarkIndex !== -1) {
|
||||
url = url.slice(0, hashmarkIndex)
|
||||
}
|
||||
|
||||
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Creates a new URL by combining the specified URLs
|
||||
*
|
||||
* @param {string} baseURL The base URL
|
||||
* @param {string} relativeURL The relative URL
|
||||
* @returns {string} The combined URL
|
||||
*/
|
||||
export default function combineURLs(baseURL, relativeURL) {
|
||||
return relativeURL
|
||||
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
||||
: baseURL
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Determines whether the specified URL is absolute
|
||||
*
|
||||
* @param {string} url The URL to test
|
||||
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
||||
*/
|
||||
export default function isAbsoluteURL(url) {
|
||||
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
||||
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
||||
// by any combination of letters, digits, plus, period, or hyphen.
|
||||
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
export type HttpTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask;
|
||||
|
||||
export type HttpRequestTask = UniApp.RequestTask;
|
||||
|
||||
export type HttpUploadTask = UniApp.UploadTask;
|
||||
|
||||
export type HttpDownloadTask = UniApp.DownloadTask;
|
||||
|
||||
export type HttpMethod =
|
||||
"GET"
|
||||
| "POST"
|
||||
| "PUT"
|
||||
| "DELETE"
|
||||
| "CONNECT"
|
||||
| "HEAD"
|
||||
| "OPTIONS"
|
||||
| "TRACE"
|
||||
| "UPLOAD"
|
||||
| "DOWNLOAD";
|
||||
|
||||
export type HttpRequestHeader = Record<string, string>;
|
||||
|
||||
export type HttpParams = Record<string, any>;
|
||||
|
||||
export type HttpData = Record<string, any>;
|
||||
|
||||
export type HttpResponseType = 'arraybuffer' | 'text';
|
||||
|
||||
export type HttpCustom = Record<string, any>;
|
||||
|
||||
export type HttpFileType = 'image' | 'video' | 'audio';
|
||||
|
||||
export type HttpFormData = Record<string, any>;
|
||||
|
||||
export type HttpResponseHeader = Record<string, string> & {
|
||||
"set-cookie"?: string[]
|
||||
};
|
||||
|
||||
export interface HttpRequestConfig<T = HttpTask> {
|
||||
/** @desc 请求服务器接口地址 */
|
||||
url?: string;
|
||||
/** @desc 请求方式,默认为 GET */
|
||||
method?: HttpMethod;
|
||||
/** @desc 请求基地址 */
|
||||
baseURL?: string;
|
||||
/** @desc 请求头信息,不能设置 Referer,App、H5 端会自动带上 cookie,且 H5 端不可手动修改 */
|
||||
header?: HttpRequestHeader;
|
||||
/** @desc 请求查询参数,自动拼接为查询字符串 */
|
||||
params?: HttpParams;
|
||||
/** @desc 请求体参数 */
|
||||
data?: HttpData;
|
||||
/** @desc 超时时间,单位 ms,默认为 60000,仅 H5 (HBuilderX 2.9.9+)、APP (HBuilderX 2.9.9+)、微信小程序 (2.10.0)、支付宝小程序支持 */
|
||||
timeout?: number;
|
||||
/** @desc 跨域请求时是否携带凭证 (cookies),默认为 false,仅 H5 (HBuilderX 2.6.15+) 支持 */
|
||||
withCredentials?: boolean;
|
||||
/** @desc 设置响应的数据类型,支付宝小程序不支持 */
|
||||
responseType?: HttpResponseType;
|
||||
/** @desc 全局自定义验证器 */
|
||||
validateStatus?: ((statusCode: number) => boolean) | null;
|
||||
|
||||
|
||||
/** params 参数自定义处理 */
|
||||
paramsSerializer?: (params: AnyObject) => string | void;
|
||||
|
||||
/** @desc 默认为 json,如果设为 json,会尝试对返回的数据做一次 JSON.parse */
|
||||
dataType?: string;
|
||||
/** @desc DNS 解析时是否优先使用 ipv4,默认为 false,仅 App-Android (HBuilderX 2.8.0+) 支持 */
|
||||
firstIpv4?: boolean;
|
||||
/** @desc 是否验证 SSL 证书,默认为 true,仅 App-Android (HBuilderX 2.3.3+) 支持 */
|
||||
sslVerify?: boolean;
|
||||
|
||||
/** @desc 开启 http2;微信小程序 */
|
||||
enableHttp2?: boolean;
|
||||
|
||||
/** @desc 开启 quic;微信小程序 */
|
||||
enableQuic?: boolean;
|
||||
/** @desc 开启 cache;微信小程序、字节跳动小程序 2.31.0+ */
|
||||
enableCache?: boolean;
|
||||
/** @desc 开启 httpDNS;微信小程序 */
|
||||
enableHttpDNS?: boolean;
|
||||
/** @desc httpDNS 服务商;微信小程序 */
|
||||
httpDNSServiceId?: string;
|
||||
/** @desc 开启 transfer-encoding chunked;微信小程序 */
|
||||
enableChunked?: boolean;
|
||||
/** @desc wifi下使用移动网络发送请求;微信小程序 */
|
||||
forceCellularNetwork?: boolean;
|
||||
/** @desc 开启后可在headers中编辑cookie;支付宝小程序 10.2.33+ */
|
||||
enableCookie?: boolean;
|
||||
/** @desc 是否开启云加速;百度小程序 3.310.11+ */
|
||||
cloudCache?: boolean | object;
|
||||
/** @desc 控制当前请求是否延时至首屏内容渲染后发送;百度小程序 3.310.11+ */
|
||||
defer?: boolean;
|
||||
|
||||
/** @desc 自定义参数 */
|
||||
custom?: HttpCustom;
|
||||
|
||||
/** @desc 返回当前请求的 task 和 options,不要在这里修改 options */
|
||||
getTask?: (task: T, options: HttpRequestConfig<T>) => void;
|
||||
|
||||
/** @desc 需要上传的文件列表,使用 files 时,filePath 和 name 不生效,仅支持 App、H5 (2.6.15+) */
|
||||
files?: { name?: string; file?: File; uri: string; }[];
|
||||
/** @desc 文件类型,仅支付宝小程序支持且为必填项 */
|
||||
fileType?: HttpFileType;
|
||||
/** @desc 要上传的文件对象,仅 H5 (2.6.15+) 支持 */
|
||||
file?: File;
|
||||
/** @desc 要上传文件资源的路径,使用 files 时,filePath 和 name 不生效 */
|
||||
filePath?: string;
|
||||
/** @desc 文件对应的 key,开发者在服务器端通过这个 key 可以获取到文件二进制内容,使用 files 时,filePath 和 name 不生效 */
|
||||
name?: string;
|
||||
/** @desc 请求中其他额外的 form data */
|
||||
formData?: HttpFormData;
|
||||
}
|
||||
|
||||
export interface HttpResponse<T = any, D = HttpTask> {
|
||||
data: T;
|
||||
statusCode: number;
|
||||
header: HttpResponseHeader;
|
||||
config: HttpRequestConfig<D>;
|
||||
cookies: string[];
|
||||
errMsg: string;
|
||||
rawData: any;
|
||||
}
|
||||
|
||||
export interface HttpUploadResponse<T = any, D = HttpTask> {
|
||||
data: T;
|
||||
statusCode: number;
|
||||
config: HttpRequestConfig<D>;
|
||||
errMsg: string;
|
||||
rawData: any;
|
||||
}
|
||||
|
||||
export interface HttpDownloadResponse extends HttpResponse {
|
||||
tempFilePath: string;
|
||||
apFilePath?: string;
|
||||
filePath?: string;
|
||||
fileContent?: string;
|
||||
}
|
||||
|
||||
export interface HttpError<T = any, D = HttpTask> {
|
||||
data?: T;
|
||||
statusCode?: number;
|
||||
header?: HttpResponseHeader;
|
||||
config: HttpRequestConfig<D>;
|
||||
cookies?: string[];
|
||||
errMsg: string;
|
||||
}
|
||||
|
||||
export interface HttpPromise<T = any> extends Promise<HttpResponse<T>> {
|
||||
}
|
||||
|
||||
export interface HttpInterceptorManager<V, E = V> {
|
||||
use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: E) => T | Promise<E>): void;
|
||||
|
||||
eject(id: number): void;
|
||||
}
|
||||
|
||||
export abstract class HttpRequestAbstract {
|
||||
constructor(config?: HttpRequestConfig);
|
||||
|
||||
interceptors: {
|
||||
request: HttpInterceptorManager<HttpRequestConfig>;
|
||||
response: HttpInterceptorManager<HttpResponse, HttpError>;
|
||||
}
|
||||
|
||||
request<T = any, R = HttpResponse<T>, D = HttpRequestTask>(config: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
get<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
delete<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
head<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
options<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
post<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
put<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
config: HttpRequestConfig;
|
||||
|
||||
setConfig<D = HttpTask>(onSend: (config: HttpRequestConfig<D>) => HttpRequestConfig<D>): void;
|
||||
|
||||
connect<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
trace<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
upload<T = any, R = HttpUploadResponse<T>, D = HttpUploadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
download<T = any, R = HttpDownloadResponse<T>, D = HttpDownloadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
|
||||
|
||||
middleware<T = any, R = HttpResponse<T>, D = HttpTask>(config: HttpRequestConfig<D>): Promise<R>;
|
||||
}
|
||||
|
||||
declare class HttpRequest extends HttpRequestAbstract {
|
||||
}
|
||||
|
||||
export default HttpRequest;
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
import Request from './core/Request'
|
||||
export default Request
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// utils is a library of generic helper functions non-specific to axios
|
||||
|
||||
var toString = Object.prototype.toString
|
||||
|
||||
/**
|
||||
* Determine if a value is an Array
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is an Array, otherwise false
|
||||
*/
|
||||
export function isArray (val) {
|
||||
return toString.call(val) === '[object Array]'
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a value is an Object
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is an Object, otherwise false
|
||||
*/
|
||||
export function isObject (val) {
|
||||
return val !== null && typeof val === 'object'
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value is a Date
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is a Date, otherwise false
|
||||
*/
|
||||
export function isDate (val) {
|
||||
return toString.call(val) === '[object Date]'
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value is a URLSearchParams object
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
||||
*/
|
||||
export function isURLSearchParams (val) {
|
||||
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over an Array or an Object invoking a function for each item.
|
||||
*
|
||||
* If `obj` is an Array callback will be called passing
|
||||
* the value, index, and complete array for each item.
|
||||
*
|
||||
* If 'obj' is an Object callback will be called passing
|
||||
* the value, key, and complete object for each property.
|
||||
*
|
||||
* @param {Object|Array} obj The object to iterate
|
||||
* @param {Function} fn The callback to invoke for each item
|
||||
*/
|
||||
export function forEach (obj, fn) {
|
||||
// Don't bother if no value provided
|
||||
if (obj === null || typeof obj === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
// Force an array if not already something iterable
|
||||
if (typeof obj !== 'object') {
|
||||
/*eslint no-param-reassign:0*/
|
||||
obj = [obj]
|
||||
}
|
||||
|
||||
if (isArray(obj)) {
|
||||
// Iterate over array values
|
||||
for (var i = 0, l = obj.length; i < l; i++) {
|
||||
fn.call(null, obj[i], i, obj)
|
||||
}
|
||||
} else {
|
||||
// Iterate over object keys
|
||||
for (var key in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
fn.call(null, obj[key], key, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为boolean 值
|
||||
* @param val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isBoolean(val) {
|
||||
return typeof val === 'boolean'
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为真正的对象{} new Object
|
||||
* @param {any} obj - 检测的对象
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isPlainObject(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Object]'
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function equal to merge with the difference being that no reference
|
||||
* to original objects is kept.
|
||||
*
|
||||
* @see merge
|
||||
* @param {Object} obj1 Object to merge
|
||||
* @returns {Object} Result of all merge properties
|
||||
*/
|
||||
export function deepMerge(/* obj1, obj2, obj3, ... */) {
|
||||
let result = {}
|
||||
function assignValue(val, key) {
|
||||
if (typeof result[key] === 'object' && typeof val === 'object') {
|
||||
result[key] = deepMerge(result[key], val)
|
||||
} else if (typeof val === 'object') {
|
||||
result[key] = deepMerge({}, val)
|
||||
} else {
|
||||
result[key] = val
|
||||
}
|
||||
}
|
||||
for (let i = 0, l = arguments.length; i < l; i++) {
|
||||
forEach(arguments[i], assignValue)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export function isUndefined (val) {
|
||||
return typeof val === 'undefined'
|
||||
}
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
/* eslint-disable */
|
||||
var clone = (function() {
|
||||
'use strict';
|
||||
|
||||
function _instanceof(obj, type) {
|
||||
return type != null && obj instanceof type;
|
||||
}
|
||||
|
||||
var nativeMap;
|
||||
try {
|
||||
nativeMap = Map;
|
||||
} catch(_) {
|
||||
// maybe a reference error because no `Map`. Give it a dummy value that no
|
||||
// value will ever be an instanceof.
|
||||
nativeMap = function() {};
|
||||
}
|
||||
|
||||
var nativeSet;
|
||||
try {
|
||||
nativeSet = Set;
|
||||
} catch(_) {
|
||||
nativeSet = function() {};
|
||||
}
|
||||
|
||||
var nativePromise;
|
||||
try {
|
||||
nativePromise = Promise;
|
||||
} catch(_) {
|
||||
nativePromise = function() {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones (copies) an Object using deep copying.
|
||||
*
|
||||
* This function supports circular references by default, but if you are certain
|
||||
* there are no circular references in your object, you can save some CPU time
|
||||
* by calling clone(obj, false).
|
||||
*
|
||||
* Caution: if `circular` is false and `parent` contains circular references,
|
||||
* your program may enter an infinite loop and crash.
|
||||
*
|
||||
* @param `parent` - the object to be cloned
|
||||
* @param `circular` - set to true if the object to be cloned may contain
|
||||
* circular references. (optional - true by default)
|
||||
* @param `depth` - set to a number if the object is only to be cloned to
|
||||
* a particular depth. (optional - defaults to Infinity)
|
||||
* @param `prototype` - sets the prototype to be used when cloning an object.
|
||||
* (optional - defaults to parent prototype).
|
||||
* @param `includeNonEnumerable` - set to true if the non-enumerable properties
|
||||
* should be cloned as well. Non-enumerable properties on the prototype
|
||||
* chain will be ignored. (optional - false by default)
|
||||
*/
|
||||
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
|
||||
if (typeof circular === 'object') {
|
||||
depth = circular.depth;
|
||||
prototype = circular.prototype;
|
||||
includeNonEnumerable = circular.includeNonEnumerable;
|
||||
circular = circular.circular;
|
||||
}
|
||||
// maintain two arrays for circular references, where corresponding parents
|
||||
// and children have the same index
|
||||
var allParents = [];
|
||||
var allChildren = [];
|
||||
|
||||
var useBuffer = typeof Buffer != 'undefined';
|
||||
|
||||
if (typeof circular == 'undefined')
|
||||
circular = true;
|
||||
|
||||
if (typeof depth == 'undefined')
|
||||
depth = Infinity;
|
||||
|
||||
// recurse this function so we don't reset allParents and allChildren
|
||||
function _clone(parent, depth) {
|
||||
// cloning null always returns null
|
||||
if (parent === null)
|
||||
return null;
|
||||
|
||||
if (depth === 0)
|
||||
return parent;
|
||||
|
||||
var child;
|
||||
var proto;
|
||||
if (typeof parent != 'object') {
|
||||
return parent;
|
||||
}
|
||||
|
||||
if (_instanceof(parent, nativeMap)) {
|
||||
child = new nativeMap();
|
||||
} else if (_instanceof(parent, nativeSet)) {
|
||||
child = new nativeSet();
|
||||
} else if (_instanceof(parent, nativePromise)) {
|
||||
child = new nativePromise(function (resolve, reject) {
|
||||
parent.then(function(value) {
|
||||
resolve(_clone(value, depth - 1));
|
||||
}, function(err) {
|
||||
reject(_clone(err, depth - 1));
|
||||
});
|
||||
});
|
||||
} else if (clone.__isArray(parent)) {
|
||||
child = [];
|
||||
} else if (clone.__isRegExp(parent)) {
|
||||
child = new RegExp(parent.source, __getRegExpFlags(parent));
|
||||
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
|
||||
} else if (clone.__isDate(parent)) {
|
||||
child = new Date(parent.getTime());
|
||||
} else if (useBuffer && Buffer.isBuffer(parent)) {
|
||||
if (Buffer.from) {
|
||||
// Node.js >= 5.10.0
|
||||
child = Buffer.from(parent);
|
||||
} else {
|
||||
// Older Node.js versions
|
||||
child = new Buffer(parent.length);
|
||||
parent.copy(child);
|
||||
}
|
||||
return child;
|
||||
} else if (_instanceof(parent, Error)) {
|
||||
child = Object.create(parent);
|
||||
} else {
|
||||
if (typeof prototype == 'undefined') {
|
||||
proto = Object.getPrototypeOf(parent);
|
||||
child = Object.create(proto);
|
||||
}
|
||||
else {
|
||||
child = Object.create(prototype);
|
||||
proto = prototype;
|
||||
}
|
||||
}
|
||||
|
||||
if (circular) {
|
||||
var index = allParents.indexOf(parent);
|
||||
|
||||
if (index != -1) {
|
||||
return allChildren[index];
|
||||
}
|
||||
allParents.push(parent);
|
||||
allChildren.push(child);
|
||||
}
|
||||
|
||||
if (_instanceof(parent, nativeMap)) {
|
||||
parent.forEach(function(value, key) {
|
||||
var keyChild = _clone(key, depth - 1);
|
||||
var valueChild = _clone(value, depth - 1);
|
||||
child.set(keyChild, valueChild);
|
||||
});
|
||||
}
|
||||
if (_instanceof(parent, nativeSet)) {
|
||||
parent.forEach(function(value) {
|
||||
var entryChild = _clone(value, depth - 1);
|
||||
child.add(entryChild);
|
||||
});
|
||||
}
|
||||
|
||||
for (var i in parent) {
|
||||
var attrs = Object.getOwnPropertyDescriptor(parent, i);
|
||||
if (attrs) {
|
||||
child[i] = _clone(parent[i], depth - 1);
|
||||
}
|
||||
|
||||
try {
|
||||
var objProperty = Object.getOwnPropertyDescriptor(parent, i);
|
||||
if (objProperty.set === 'undefined') {
|
||||
// no setter defined. Skip cloning this property
|
||||
continue;
|
||||
}
|
||||
child[i] = _clone(parent[i], depth - 1);
|
||||
} catch(e){
|
||||
if (e instanceof TypeError) {
|
||||
// when in strict mode, TypeError will be thrown if child[i] property only has a getter
|
||||
// we can't do anything about this, other than inform the user that this property cannot be set.
|
||||
continue
|
||||
} else if (e instanceof ReferenceError) {
|
||||
//this may happen in non strict mode
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
var symbols = Object.getOwnPropertySymbols(parent);
|
||||
for (var i = 0; i < symbols.length; i++) {
|
||||
// Don't need to worry about cloning a symbol because it is a primitive,
|
||||
// like a number or string.
|
||||
var symbol = symbols[i];
|
||||
var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
|
||||
if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
|
||||
continue;
|
||||
}
|
||||
child[symbol] = _clone(parent[symbol], depth - 1);
|
||||
Object.defineProperty(child, symbol, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeNonEnumerable) {
|
||||
var allPropertyNames = Object.getOwnPropertyNames(parent);
|
||||
for (var i = 0; i < allPropertyNames.length; i++) {
|
||||
var propertyName = allPropertyNames[i];
|
||||
var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
|
||||
if (descriptor && descriptor.enumerable) {
|
||||
continue;
|
||||
}
|
||||
child[propertyName] = _clone(parent[propertyName], depth - 1);
|
||||
Object.defineProperty(child, propertyName, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
return _clone(parent, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple flat clone using prototype, accepts only objects, usefull for property
|
||||
* override on FLAT configuration object (no nested props).
|
||||
*
|
||||
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
|
||||
* works.
|
||||
*/
|
||||
clone.clonePrototype = function clonePrototype(parent) {
|
||||
if (parent === null)
|
||||
return null;
|
||||
|
||||
var c = function () {};
|
||||
c.prototype = parent;
|
||||
return new c();
|
||||
};
|
||||
|
||||
// private utility functions
|
||||
|
||||
function __objToStr(o) {
|
||||
return Object.prototype.toString.call(o);
|
||||
}
|
||||
clone.__objToStr = __objToStr;
|
||||
|
||||
function __isDate(o) {
|
||||
return typeof o === 'object' && __objToStr(o) === '[object Date]';
|
||||
}
|
||||
clone.__isDate = __isDate;
|
||||
|
||||
function __isArray(o) {
|
||||
return typeof o === 'object' && __objToStr(o) === '[object Array]';
|
||||
}
|
||||
clone.__isArray = __isArray;
|
||||
|
||||
function __isRegExp(o) {
|
||||
return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
|
||||
}
|
||||
clone.__isRegExp = __isRegExp;
|
||||
|
||||
function __getRegExpFlags(re) {
|
||||
var flags = '';
|
||||
if (re.global) flags += 'g';
|
||||
if (re.ignoreCase) flags += 'i';
|
||||
if (re.multiline) flags += 'm';
|
||||
return flags;
|
||||
}
|
||||
clone.__getRegExpFlags = __getRegExpFlags;
|
||||
|
||||
return clone;
|
||||
})();
|
||||
|
||||
export default clone
|
||||
Loading…
Reference in New Issue