UNPKG

formily-request-monorepo

Version:

A flexible, lightweight, non-intrusive plugin for extending formily schema request data.

197 lines (149 loc) 6.07 kB
[![NPM Package](https://img.shields.io/npm/v/formily-request.svg)](https://www.npmjs.org/package/formily-request) [![Minified Size](https://img.shields.io/bundlephobia/min/formily-request.svg?label=minified)](https://bundlephobia.com/result?p=formily-request) [![Gzipped Size](https://img.shields.io/bundlephobia/minzip/formily-request.svg?label=gzipped)](https://bundlephobia.com/result?p=formily-request) Formily Request 是一个灵活、轻量、无侵入性,扩展 json schema 配置的请求数据插件。 - 组件无关,不用写额外的自定义组件 - 框架无关,不用关注是 Vue 还是 React - 组件库无关,不用关注是 Ant Design 还是 Element Plus - 高扩展性,可用于 Select、Radio、Checkbox、Cascader 等任何动态数据的组件 [Demo](https://codesandbox.io/s/hardcore-brahmagupta-tshn42?file=/src/App.tsx) / [Examples](https://007sair.github.io/formily-request/examples) / [API 文档](https://github.com/007sair/formily-request/docs/classes/FormilyRequest) ## 安装 **该插件需要 peer 依赖 `@formil/reactive@>=2.2.27`,请先确保已经安装。** ```sh $ npm i formily-request ``` ## 使用 ```tsx import { Schema } from "@formily/react"; // or @formily/vue import fxr from "formily-request"; // 1.引入 formily-request // 2.使用Schema类、调用注册函数 fxr.use(Schema).register(); const schema: ISchema = { type: "object", properties: { select: { type: "string", "x-component": "Select", // 3.配置x-request "x-request": {}, }, }, }; export default () => { return <SchemaField schema={schema} />; }; ``` ## 配置 为满足不同的使用需求,`x-request`提供了 3 种配置方式: ### 方式一,使用内置`fetch` ```json { "x-request": { "url": "http://xxx.xx.com", "method": "post", "credentials": "include", "headers": { "Content-Type": "application/json" } } } ``` 该方式使用了插件内置的`fetch`发起请求,并未做过多的封装,除了 url、method,还可以在`x-request`内使用`header`等任何 [fetch](https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API) 的配置。 但是,这种方式也有使用限制,由于 schema 是静态配置,当 url 地址需要在不同开发环境发生变化,例如,开发环境使用了`/api`作为前缀,生成环境使用`http://`开头的场景,此时,就需要使用`register`的参数: ```tsx import fxr from "formily-request"; // 记得先 use(Schema) fxr.register({ baseURL: import.meta.env.BASIC_API, // 全局配置 }); ``` 除了 `baseURL`,一些全局、不想在 scheme 上重复配置的参数也可以在这里(或组件内)配置。 **注意:** 使用 url 配置方式时,`x-request.params`必须为`object`类型,否则无法解析参数。 ### 方式二,使用`service` 方式一的内置 fetch 如果无法满足请求,或者有一些定制的逻辑处理,如:token 验证、响应拦截、错误处理...等,可以使用`service`配置: ```tsx // 1.声明一些业务使用的请求函数,返回类型为 Promise 即可 const queryUser = (params: { name: string }) => { return axios('/xxx/yyy', { params, method: 'GET' }) } // 2.在scope中注入 <SchemaField scope={{ queryUser }} /> // 3.在schema配置中使用 { "x-request": { "service": "{{ queryUser }}", "params": { name: '' // 这里可以使用表达式处理一些其他字段依赖,如: '{{ $values.xx }}' }, } } ``` ### 方式三,使用`customService` 如果不想使用内置的 fetch,又想使用 x-request 配置,可以使用该方式,它介于一、二之间,例如: ```tsx import type { RequestObject } from "formily-request"; // 入参为x-request配置项 const queryUser = (requestConfig: RequestObject) => { const { url, params, method } = RequestObject; return jsonp(url, { method, params }); }; // 在scope中注入 <SchemaField scope={{ queryUser }} /> // 在schema配置中使用 { "x-request": { "customService": "{{ queryUser }}", // 这里不再是service "params": { name: '' // 这里可以使用表达式处理一些其他字段依赖,如: '{{ $values.xx }}' }, } } ``` 如果同时配置了以上 3 种方式,优先级为 `customService` > `service` > `内置 fetch`。 ## 关于联动 目前已知的联动场景如下: - 字段联动,如:省市区、库表等; - `Select`组件的`onSearch`事件会触发接口的二次请求; 字段联动场景比较简单,不做赘述,这里主要讲一下 `onSearch` 主动触发场景: ```ts { "x-component": "Select", "x-component-props": { onSearch: '{{ v => $self.invoke("updateRequest", request => request.params.keyword = v) }}' }, "x-request": { "url": "", "params": { keyword: "" } } } ``` `updateRequest`为插件注入的自定义方法,调用`$self.invoke`,参数为函数,函数入参为配置的`x-request`配置,通过改写具体属性,可实现接口的响应式更新。 对于 Select 组件的搜索场景,可以参考 demo:[example-basic-jsonp--search](https://007sair.github.io/formily-request/?path=/story/example-basic-jsonp--search) ## 自定义事件 formily-request 内部使用 `field.inject()` 注册了 `updateRequest` 方法,可以使用如下方式在 schema 配置中使用: ```json { "x-component-props": { "onSearch": "{{ $self.invoke('updateRequest', request => request.xxx.xxx) }}" } } ``` invoke 类型如下: ```tsx $self.invoke("updateRequest", (request: XRequest) => void) ``` 可以在第 2 个参数内修改 request 的属性值,修改后会重新发起请求,常用于 Select 组件的 onSearch 方法中: ```json { "x-component": "Select", "x-component-props": { "onSearch": "{{ str => $self.invoke('updateRequest', r => r.params.keyword = str) }}" }, "x-request": { "url": "xx/xxx", "params": { "keyword": "" } // 触发 onSearch 后这里的 keyword 会更新,触发响应式更新 } } ```