From c77f8fcea0c39976924bea03cd546d9137d5ce9a Mon Sep 17 00:00:00 2001 From: qlin Date: Thu, 4 Aug 2022 19:45:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20script=20setup=20=E6=94=AF=E6=8C=81=20d?= =?UTF-8?q?efineRouteMeta=20(#144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reference/plugin/plugins/request.md | 184 +++++++++++------- .../src/plugins/misc/route/index.js | 9 +- 2 files changed, 124 insertions(+), 69 deletions(-) diff --git a/docs/reference/plugin/plugins/request.md b/docs/reference/plugin/plugins/request.md index da9fc7a2..7f138044 100644 --- a/docs/reference/plugin/plugins/request.md +++ b/docs/reference/plugin/plugins/request.md @@ -1,17 +1,20 @@ # @fesjs/plugin-request 基于 axios 封装的 request,内置防止重复请求、请求节流、错误处理等功能。 + ## 启用方式 在 `package.json` 中引入依赖: + ```json { "dependencies": { "@fesjs/fes": "^2.0.0", "@fesjs/plugin-request": "^2.0.0" - }, + } } ``` + ## 配置 ### 构建时配置 @@ -20,26 +23,25 @@ export default { request: { dataField: 'result' - }, -} + } +}; ``` #### dataField -- 类型: `string` -- 默认值: `''` -- 详情: +- 类型: `string` +- 默认值: `''` +- 详情: `dataField` 对应接口统一格式中的数据字段,比如接口如果统一的规范是 `{ success: boolean, result: any}` ,那么就不需要配置,这样你通过 `useRequest` 消费的时候会生成一个默认的 `formatResult`,直接返回 `result` 中的数据,方便使用。如果你的后端接口不符合这个规范,可以自行配置 `dataField`。配置为 `''`(空字符串)的时候不做处理。 - #### base(即将废弃) -- 类型: `string` -- 默认值: `''` -- 详情: +- 类型: `string` +- 默认值: `''` +- 详情: - `base` 接口前缀。 + `base` 接口前缀。 ::: warning 即将废弃 这个字段将在下个版本废弃,推荐使用 [axios baseURL](https://github.com/axios/axios)。 @@ -48,7 +50,7 @@ export default { ### 运行时配置 在 `app.js` 中进行运行时配置。 - + ```js export const request = { // 格式化 response.data (只有 response.data 类型为 object 才会调用) @@ -58,7 +60,7 @@ export const request = { }, // 关闭 response data 校验(只判断 xhr status) closeResDataCheck: false, - // 请求拦截器 + // 请求拦截器 http://axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8 requestInterceptors: [], // 响应拦截器 responseInterceptors: [], @@ -69,57 +71,58 @@ export const request = { 11199(response) { // 特殊 code 处理逻辑 }, - 404(error) { - }, + 404(error) {}, default(error) { // 异常统一处理 } }, // 其他 axios 配置 ...otherConfigs -} +}; ``` #### skipErrorHandler -- 类型: `boolean | string | number | array` -- 默认值: `` -- 详情: +- 类型: `boolean | string | number | array` +- 默认值: `` +- 详情: 指定当前请求的某些错误状态不走 `errorHandler`,单独进行处理。如果设置为 `true`,当前请求的错误处理都不走 `errorHandler`。 -- 示列: +- 示列: ```js -import {request} from '@fesjs/fes'; +import { request } from '@fesjs/fes'; request('/api/login', null, { skipErrorHandler: '110' -}).then((res) => { - // do something -}).catch((err) => { - // 这里处理 code 为 110 的异常 - // 此时 errorHandler[110] 函数不会生效,也不会执行 errorHandler.default }) + .then((res) => { + // do something + }) + .catch((err) => { + // 这里处理 code 为 110 的异常 + // 此时 errorHandler[110] 函数不会生效,也不会执行 errorHandler.default + }); ``` - - ## 使用 ### 发起一个普通 post 请求 ```js -import {request} from '@fesjs/fes'; +import { request } from '@fesjs/fes'; request('/api/login', { username: 'robby', password: '123456' -}).then((res) => { - // do something -}).catch((err) => { - // 处理异常 }) + .then((res) => { + // do something + }) + .catch((err) => { + // 处理异常 + }); ``` ### merge 重复请求 @@ -129,73 +132,121 @@ request('/api/login', { 当发生 `REPEAT` 请求异常,并且确保自身代码合理的情况下,可以使用该配置。 ```js -import {request} from '@fesjs/fes'; +import { request } from '@fesjs/fes'; -request('/api/login', { - username: 'robby', - password: '123456' -}, { - mergeRequest: true, // 在一个请求没有回来前,重复发送的请求会合并成一个请求 -}).then((res) => { - // do something -}).catch((err) => { - // 处理异常 -}) +request( + '/api/login', + { + username: 'robby', + password: '123456' + }, + { + mergeRequest: true // 在一个请求没有回来前,重复发送的请求会合并成一个请求 + } +) + .then((res) => { + // do something + }) + .catch((err) => { + // 处理异常 + }); ``` ### 请求节流(即将废弃) - ::: warning 即将废弃 因为 request 的请求总会有一个 promise 结果,要么成功,要么失败,和防抖、节流的语义不一致,防抖、节流只是函数的不执行 ::: - ### 请求缓存 ```js -import {request} from '@fesjs/fes'; +import { request } from '@fesjs/fes'; -request('/api/login', { - username: 'robby', - password: '123456' -}, { - cache: { - cacheType: 'ram', // ram: 内存,session: sessionStorage,local:localStorage - cacheTime: 1000 * 60 * 3 // 缓存时间:默认3min +request( + '/api/login', + { + username: 'robby', + password: '123456' }, -}).then((res) => { - // do something -}).catch((err) => { - // 处理异常 -}) + { + cache: { + cacheType: 'ram', // ram: 内存,session: sessionStorage,local:localStorage + cacheTime: 1000 * 60 * 3 // 缓存时间:默认3min + } + } +) + .then((res) => { + // do something + }) + .catch((err) => { + // 处理异常 + }); ``` 若 `cache` 传 `true`,则默认使用 `ram` 缓存类型,缓存时间 3min。 - ### 结合 use 使用 ```js -import {useRequest} from '@fesjs/fes'; - +import { useRequest } from '@fesjs/fes'; export default { setup() { - const {loading, data, error} = useRequest('/api/login', { + const { loading, data, error } = useRequest('/api/login', { username: 'robby', password: '123456' - }) + }); return { loading, data, error - } + }; } -} +}; ``` +### 配置拦截器 + +函数的参数格式:[传送门](http://axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8); + +```js +export const request = { + requestInterceptors: [ + function (config) { + // 在发送请求之前做些什么 + return config; + }, + [ + function (config) { + // 在发送请求之前做些什么 + return config; + }, function (error) { + // 对请求错误做些什么 + return Promise.reject(error); + } + ] + ], + // 响应拦截器 + responseInterceptors: [ + function (response) { + // 对响应数据做点什么 + return response; + }, + [ + function (response) { + // 对响应数据做点什么 + return response; + }, function (error) { + // 对响应错误做点什么 + return Promise.reject(error); + } + ] + ], +} + + ## API ### request @@ -212,3 +263,4 @@ export default { ### useRequest request 的封装,返回响应式 `loading`、`error`、 `data` +``` diff --git a/packages/fes-preset-built-in/src/plugins/misc/route/index.js b/packages/fes-preset-built-in/src/plugins/misc/route/index.js index e2b46985..4d564c30 100644 --- a/packages/fes-preset-built-in/src/plugins/misc/route/index.js +++ b/packages/fes-preset-built-in/src/plugins/misc/route/index.js @@ -112,7 +112,7 @@ const genRoutes = function (parentRoutes, path, parentRoutePath) { const routeName = getRouteName(parentRoutePath, fileName); const componentPath = winPath(filePath); - let content = readFileSync(filePath, 'utf-8'); + const content = readFileSync(filePath, 'utf-8'); let routeMeta = {}; if (ext === '.vue') { const { descriptor } = parse(content); @@ -121,8 +121,11 @@ const genRoutes = function (parentRoutes, path, parentRoutePath) { ); routeMeta = routeMetaBlock?.content ? JSON.parse(routeMetaBlock.content) : {}; if (descriptor.script) { - content = descriptor.script.content; - routeMeta = getRouteMeta(content) || routeMeta; + routeMeta = getRouteMeta(descriptor.script.content) || routeMeta; + } + // 优先使用 descriptor.script, 兼容 script 和 script setup 同时存在的情况 + if (descriptor.scriptSetup && lodash.isEmpty(routeMeta)) { + routeMeta = getRouteMeta(descriptor.scriptSetup.content) || routeMeta; } } if (ext === '.jsx' || ext === '.tsx') {