diff --git a/packages/antd/docs/components/Cascader.md b/packages/antd/docs/components/Cascader.md index 647ebe167fb..8433131a31e 100644 --- a/packages/antd/docs/components/Cascader.md +++ b/packages/antd/docs/components/Cascader.md @@ -10,7 +10,7 @@ import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -94,7 +94,7 @@ import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -186,7 +186,7 @@ import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, Field } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const useAddress = (pattern: Formily.Core.Types.FormPathPattern) => { const transform = (data = {}) => { diff --git a/packages/antd/docs/components/Select.md b/packages/antd/docs/components/Select.md index 6b97acbe151..a928c026bee 100644 --- a/packages/antd/docs/components/Select.md +++ b/packages/antd/docs/components/Select.md @@ -54,7 +54,7 @@ import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -156,306 +156,3 @@ export default () => ( ) ``` - -## JSON Schema 同步数据源案例 - -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const form = createForm() - -const schema = { - type: 'object', - properties: { - select: { - type: 'string', - title: '选择框', - 'x-decorator': 'FormItem', - 'x-component': 'Select', - enum: [ - { label: '选项1', value: 1 }, - { label: '选项2', value: 2 }, - ], - 'x-component-props': { - style: { - width: 120, - }, - }, - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` - -## JOSN Schema 异步联动数据源案例 - -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, createSchemaField } from '@formily/react' -import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' - -const SchemaField = createSchemaField({ - components: { - Select, - FormItem, - }, -}) - -const loadData = async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) -} - -const useAsyncDataSource = (service) => (field) => { - field.setComponentProps({ - suffixIcon: , - }) - service(field).then( - action((data) => { - field.setDataSource(data) - field.setComponentProps({ - suffixIcon: undefined, - }) - }) - ) -} - -const form = createForm() - -const schema = { - type: 'object', - properties: { - linkage: { - type: 'string', - title: '联动选择框', - enum: [ - { label: '发请求1', value: 1 }, - { label: '发请求2', value: 2 }, - ], - 'x-decorator': 'FormItem', - 'x-component': 'Select', - 'x-component-props': { - style: { - width: 120, - }, - }, - }, - select: { - type: 'string', - title: '异步选择框', - 'x-decorator': 'FormItem', - 'x-component': 'Select', - 'x-component-props': { - style: { - width: 120, - }, - }, - 'x-reactions': ['{{useAsyncDataSource(loadData)}}'], - }, - }, -} - -export default () => ( - - - - 提交 - - -) -``` - -## 纯 JSX 同步数据源案例 - -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm } from '@formily/core' -import { FormProvider, Field } from '@formily/react' -import { LoadingOutlined } from '@ant-design/icons' - -const form = createForm() - -export default () => ( - - - - 提交 - - -) -``` - -## 纯 JSX 异步联动数据源案例 - -```tsx -import React from 'react' -import { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd' -import { createForm, onFieldReact } from '@formily/core' -import { FormProvider, Field } from '@formily/react' -import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' - -const useAsyncDataSource = ( - pattern: Formily.Core.Types.FormPathPattern, - service: ( - field: Formily.Core.Models.Field - ) => Promise<{ label: string; value: any }[]> -) => { - onFieldReact(pattern, (field) => { - field.setComponentProps({ - suffixIcon: , - }) - service(field).then( - action((data) => { - field.setDataSource(data) - field.setComponentProps({ - suffixIcon: undefined, - }) - }) - ) - }) -} - -const form = createForm({ - effects: () => { - useAsyncDataSource('select', async (field) => { - const linkage = field.query('linkage').get('value') - if (!linkage) return [] - return new Promise((resolve) => { - setTimeout(() => { - if (linkage === 1) { - resolve([ - { - label: 'AAA', - value: 'aaa', - }, - { - label: 'BBB', - value: 'ccc', - }, - ]) - } else if (linkage === 2) { - resolve([ - { - label: 'CCC', - value: 'ccc', - }, - { - label: 'DDD', - value: 'ddd', - }, - ]) - } - }, 1500) - }) - }) - }, -}) - -export default () => ( - - - - - 提交 - - -) -``` - -## API - -参考 https://ant.design/components/select-cn/ diff --git a/packages/antd/docs/components/TreeSelect.md b/packages/antd/docs/components/TreeSelect.md index 91a2cb6a3c5..ed2944c1464 100644 --- a/packages/antd/docs/components/TreeSelect.md +++ b/packages/antd/docs/components/TreeSelect.md @@ -99,7 +99,7 @@ import { import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -379,7 +379,7 @@ import { import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -631,7 +631,7 @@ import { import { createForm, onFieldReact } from '@formily/core' import { FormProvider, Field } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const useAsyncDataSource = ( pattern: Formily.Core.Types.FormPathPattern, diff --git a/packages/antd/docs/components/index.md b/packages/antd/docs/components/index.md index 97ee07367dc..bd8f39b60be 100644 --- a/packages/antd/docs/components/index.md +++ b/packages/antd/docs/components/index.md @@ -60,7 +60,7 @@ ## 安装 ```bash -$ npm install --save antd mobx moment +$ npm install --save antd moment $ npm install --save @formily/core @formily/react @formily/antd ``` diff --git a/packages/antd/docs/index.md b/packages/antd/docs/index.md index 31923aecf73..fafebe93447 100644 --- a/packages/antd/docs/index.md +++ b/packages/antd/docs/index.md @@ -25,7 +25,7 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by sel ## 安装 ```bash -$ npm install --save antd mobx moment +$ npm install --save antd moment $ npm install --save @formily/core @formily/react @formily/antd ``` diff --git a/packages/antd/src/form-collapse/index.tsx b/packages/antd/src/form-collapse/index.tsx index 6d1e51a377b..5bc78618e1b 100644 --- a/packages/antd/src/form-collapse/index.tsx +++ b/packages/antd/src/form-collapse/index.tsx @@ -1,6 +1,6 @@ import React, { Fragment, useMemo } from 'react' import { Collapse, Badge } from 'antd' -import { createModel } from '@formily/reactive' +import { model } from '@formily/reactive' import { CollapseProps, CollapsePanelProps } from 'antd/lib/collapse' import { useField, @@ -56,7 +56,7 @@ const usePanels = () => { } const createFormCollapse = (defaultActiveKeys?: ActiveKeys) => { - const formCollapse = createModel({ + const formCollapse = model({ activeKeys: defaultActiveKeys || [], setActiveKeys(keys: ActiveKeys) { formCollapse.activeKeys = keys diff --git a/packages/antd/src/form-step/index.tsx b/packages/antd/src/form-step/index.tsx index 2ff1e8b6215..c8bbf94aed7 100644 --- a/packages/antd/src/form-step/index.tsx +++ b/packages/antd/src/form-step/index.tsx @@ -1,5 +1,5 @@ import React, { Fragment } from 'react' -import { createModel } from '@formily/reactive' +import { action, model } from '@formily/reactive' import { Steps } from 'antd' import cls from 'classnames' import { StepsProps, StepProps } from 'antd/lib/steps' @@ -66,7 +66,7 @@ const createFormStep = (defaultCurrent = 0): IFormStep => { steps: [], } - const setDisplay = (target: number) => { + const setDisplay = action((target: number) => { const currentStep = env.steps[target] env.steps.forEach(({ name }) => { env.form.query(`${env.field.address}.${name}`).take((field) => { @@ -77,23 +77,23 @@ const createFormStep = (defaultCurrent = 0): IFormStep => { } }) }) - } + }) - const next = () => { + const next = action(() => { if (formStep.allowNext) { setDisplay(formStep.current + 1) formStep.setCurrent(formStep.current + 1) } - } + }) - const back = () => { + const back = action(() => { if (formStep.allowBack) { setDisplay(formStep.current - 1) formStep.setCurrent(formStep.current - 1) } - } + }) - const formStep: IFormStep = createModel({ + const formStep: IFormStep = model({ connect(steps, field) { env.steps = steps env.form = field?.form diff --git a/packages/antd/src/form-tab/index.tsx b/packages/antd/src/form-tab/index.tsx index 970ee9acc0f..4cd7f902080 100644 --- a/packages/antd/src/form-tab/index.tsx +++ b/packages/antd/src/form-tab/index.tsx @@ -1,6 +1,6 @@ import React, { Fragment, useMemo } from 'react' import { Tabs, Badge } from 'antd' -import { createModel } from '@formily/reactive' +import { model } from '@formily/reactive' import { TabPaneProps, TabsProps } from 'antd/lib/tabs' import { useField, @@ -51,7 +51,7 @@ const useTabs = () => { } const createFormTab = (defaultActiveKey?: string) => { - const formTab = createModel({ + const formTab = model({ activeKey: defaultActiveKey, setActiveKey(key: string) { formTab.activeKey = key diff --git a/packages/core/docs/api/models/Field.md b/packages/core/docs/api/models/Field.md index 00ed641c13a..bd03ff835dc 100644 --- a/packages/core/docs/api/models/Field.md +++ b/packages/core/docs/api/models/Field.md @@ -6,13 +6,7 @@ order: 1 调用[createField](/api/models/form#createfield)所返回的 Field 模型。 -以下会列出所有模型属性,如果该属性是可写的,那么我们可以直接引用是修改该属性,Mobx 便会响应从而触发 UI 更新。 - - - -注意,要在 mobx action 中修改属性。如果在 formily 给出的回调函数中直接修改,则不需要包装 action,如果在异步回调中则需要包装,当然你也可以直接调用 Setters 方法。 - - +以下会列出所有模型属性,如果该属性是可写的,那么我们可以直接引用是修改该属性,@formily/reactive 便会响应从而触发 UI 更新。 ## 属性 diff --git a/packages/core/docs/api/models/Form.md b/packages/core/docs/api/models/Form.md index 16dbf8ce1c0..57a5ff27e09 100644 --- a/packages/core/docs/api/models/Form.md +++ b/packages/core/docs/api/models/Form.md @@ -4,13 +4,7 @@ order: 0 # Form -调用[createForm](/api/entry/create-form)所返回的核心[表单模型](/guide/form) API,以下会列出所有模型属性,如果该属性是可写的,那么我们可以直接引用是修改该属性,Mobx 便会响应从而触发 UI 更新。 - - - -注意,要在 mobx action 中修改属性。如果在 formily 给出的回调函数中直接修改,则不需要包装 action,如果在异步回调中则需要包装,当然你也可以直接调用 Setters 方法。 - - +调用[createForm](/api/entry/create-form)所返回的核心[表单模型](/guide/form) API,以下会列出所有模型属性,如果该属性是可写的,那么我们可以直接引用是修改该属性,@formily/reactive 便会响应从而触发 UI 更新。 ## 属性 diff --git a/packages/core/docs/api/models/VoidField.md b/packages/core/docs/api/models/VoidField.md index 523e9204e2a..64266da1996 100644 --- a/packages/core/docs/api/models/VoidField.md +++ b/packages/core/docs/api/models/VoidField.md @@ -6,13 +6,7 @@ order: 4 调用[createVoidField](/api/models/form#createvoidfield)所返回的 VoidField 模型。 -以下会列出所有模型属性,如果该属性是可写的,那么我们可以直接引用是修改该属性,Mobx 便会响应从而触发 UI 更新。 - - - -注意,要在 mobx action 中修改属性。如果在 formily 给出的回调函数中直接修改,则不需要包装 action,如果在异步回调中则需要包装,当然你也可以直接调用 Setters 方法。 - - +以下会列出所有模型属性,如果该属性是可写的,那么我们可以直接引用是修改该属性,@formily/reactive 便会响应从而触发 UI 更新。 ## 属性 diff --git a/packages/core/docs/guide/architecture.md b/packages/core/docs/guide/architecture.md index 114d1243441..9cc2e49bb61 100644 --- a/packages/core/docs/guide/architecture.md +++ b/packages/core/docs/guide/architecture.md @@ -8,9 +8,9 @@ Formily 内核架构非常复杂,因为要解决一个领域级的问题,而 ## 说明 -从上图中我们可以看到 Formily 内核其实是一个 Mobx 领域模型。 +从上图中我们可以看到 Formily 内核其实是一个 @formily/reactive 领域模型。 -实际消费领域模型则主要是依赖 Mobx 的 响应器 机制做依赖追踪来消费。 +实际消费领域模型则主要是依赖 @formily/reactive 的 响应器 机制做依赖追踪来消费。 我们可以在响应器(Reactions)中消费 Form/Field/ArrayField/ObjectField/VoidField 模型中的任意属性,依赖的属性发生变化,响应器就会重复执行。 diff --git a/packages/core/docs/guide/form.md b/packages/core/docs/guide/form.md index 96ddd4328a5..46b3e75411e 100644 --- a/packages/core/docs/guide/form.md +++ b/packages/core/docs/guide/form.md @@ -71,7 +71,7 @@ - 字段默认值(initialValue)管理 - 值与默认值的选择合并策略 -表单值管理,其实就是一个对象结构的 values 属性,只是它是一个 Mobx observable 属性,同时借助了 Mobx 的深度 observer 能力,监听了它任意属性变化,如果发生变化,便会触发 onFormValuesChange 的生命周期钩子。 +表单值管理,其实就是一个对象结构的 values 属性,只是它是一个 @formily/reactive observable 属性,同时借助了 @formily/reactive 的深度 observer 能力,监听了它任意属性变化,如果发生变化,便会触发 onFormValuesChange 的生命周期钩子。 同理,默认值管理其实也是一个对象结构的 initialValues 属性,同样会深度监听属性变化,触发 onFormInitialValues 的生命周期钩子。 diff --git a/packages/core/docs/guide/index.md b/packages/core/docs/guide/index.md index 9ddcfb8aacd..965f049394b 100644 --- a/packages/core/docs/guide/index.md +++ b/packages/core/docs/guide/index.md @@ -10,7 +10,7 @@ ## 超高性能 -借助 Mobx6,@formily/core 天然获得了依赖追踪,高效更新,按需渲染的能力,不管是在 React 下,还是 Vue/Angular 下,不管是字段频繁输入,还是字段联动,都能给用户带来 O(1)的性能体验,开发者无需关心性能优化的事情,只需要专注于业务逻辑实现即可。 +借助 @formily/reactive,@formily/core 天然获得了依赖追踪,高效更新,按需渲染的能力,不管是在 React 下,还是 Vue/Angular 下,不管是字段频繁输入,还是字段联动,都能给用户带来 O(1)的性能体验,开发者无需关心性能优化的事情,只需要专注于业务逻辑实现即可。 ## 领域模型 diff --git a/packages/core/docs/index.md b/packages/core/docs/index.md index 15c11b99e43..b028f7fe0ff 100644 --- a/packages/core/docs/index.md +++ b/packages/core/docs/index.md @@ -34,7 +34,6 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by sel ## 安装 ```bash -$ npm install --save mobx $ npm install --save @formily/core ``` @@ -57,7 +56,7 @@ $ npm install --save @formily/core */ import React, { createContext, useMemo, useContext, useEffect } from 'react' import { createForm, setValidateLanguage } from '@formily/core' -import { observer } from 'mobx-react-lite' +import { observer } from '@formily/reactive-react' //创建上下文,方便Field消费 const FormContext = createContext() diff --git a/packages/core/src/models/Field.ts b/packages/core/src/models/Field.ts index 6784b4f56d1..8e52c8f9936 100644 --- a/packages/core/src/models/Field.ts +++ b/packages/core/src/models/Field.ts @@ -51,8 +51,8 @@ import { queryFeedbacks, queryFeedbackMessages, getValuesFromEvent, - createModelStateSetter, - createModelStateGetter, + modelStateSetter, + modelStateGetter, } from '../shared' import { Query } from './Query' @@ -642,9 +642,9 @@ export class Field< } } - setState: IModelSetter = createModelStateSetter(this) + setState: IModelSetter = modelStateSetter(this) - getState: IModelGetter = createModelStateGetter(this) + getState: IModelGetter = modelStateGetter(this) onInit = () => { this.initialized = true diff --git a/packages/core/src/models/Form.ts b/packages/core/src/models/Form.ts index 00999604611..f4b7a2e476b 100644 --- a/packages/core/src/models/Form.ts +++ b/packages/core/src/models/Form.ts @@ -42,8 +42,8 @@ import { import { isVoidField, runEffects, - createModelStateGetter, - createModelStateSetter, + modelStateGetter, + modelStateSetter, createFieldStateSetter, createFieldStateGetter, applyValuesPatch, @@ -563,13 +563,13 @@ export class Form { } } - setState: IModelSetter = createModelStateSetter(this) + setState: IModelSetter = modelStateSetter(this) - getState: IModelGetter = createModelStateGetter(this) + getState: IModelGetter = modelStateGetter(this) - setFormState: IModelSetter = createModelStateSetter(this) + setFormState: IModelSetter = modelStateSetter(this) - getFormState: IModelGetter = createModelStateGetter(this) + getFormState: IModelGetter = modelStateGetter(this) setFieldState: IFieldStateSetter = createFieldStateSetter(this) diff --git a/packages/core/src/models/VoidField.ts b/packages/core/src/models/VoidField.ts index 762dc863df9..b61afaacf6c 100644 --- a/packages/core/src/models/VoidField.ts +++ b/packages/core/src/models/VoidField.ts @@ -22,8 +22,8 @@ import { } from '../types' import { buildNodeIndexes, - createModelStateGetter, - createModelStateSetter, + modelStateGetter, + modelStateSetter, publishUpdate, } from '../shared' import { Form } from './Form' @@ -328,9 +328,9 @@ export class VoidField { } } - setState: IModelSetter = createModelStateSetter(this) + setState: IModelSetter = modelStateSetter(this) - getState: IModelGetter = createModelStateGetter(this) + getState: IModelGetter = modelStateGetter(this) onInit = () => { this.initialized = true diff --git a/packages/core/src/shared/internals.ts b/packages/core/src/shared/internals.ts index 48f56dda47f..c1d937900d4 100644 --- a/packages/core/src/shared/internals.ts +++ b/packages/core/src/shared/internals.ts @@ -10,7 +10,7 @@ import { isPlainObj, } from '@formily/shared' import { ValidatorTriggerType, validate } from '@formily/validator' -import { batchable, batch, toJS } from '@formily/reactive' +import { action, batch, toJS } from '@formily/reactive' import { Field, ArrayField, Form } from '../models' import { ISpliceArrayStateProps, @@ -447,16 +447,16 @@ export const getModelState = (model: any, getter?: any) => { } } -export const createModelStateSetter = (model: any) => { - return batchable((state?: any) => setModelState(model, state)) +export const modelStateSetter = (model: any) => { + return action((state?: any) => setModelState(model, state)) } -export const createModelStateGetter = (model: any) => { +export const modelStateGetter = (model: any) => { return (getter?: any) => getModelState(model, getter) } export const createFieldStateSetter = (form: Form) => { - return batchable((pattern: FieldMatchPattern, payload?: any) => { + return action((pattern: FieldMatchPattern, payload?: any) => { if (isQuery(pattern)) { pattern.forEach((field) => { field.setState(payload) diff --git a/packages/json-schema/src/compiler.ts b/packages/json-schema/src/compiler.ts index 892d1cdef50..abe08a96fcf 100644 --- a/packages/json-schema/src/compiler.ts +++ b/packages/json-schema/src/compiler.ts @@ -63,6 +63,9 @@ export const compile = ( if (isFn(source['toJSON'])) { return source } + if (isObservable(source)) { + return source + } if (seenObjects.get(source)) { return source } diff --git a/packages/next/docs/components/Cascader.md b/packages/next/docs/components/Cascader.md index 74f93dc0f53..5b30fe05ad6 100644 --- a/packages/next/docs/components/Cascader.md +++ b/packages/next/docs/components/Cascader.md @@ -10,7 +10,7 @@ import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -94,7 +94,7 @@ import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -186,7 +186,7 @@ import { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next' import { createForm } from '@formily/core' import { FormProvider, onFieldReact, Field } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const useAddress = (pattern: Formily.Core.Types.FormPathPattern) => { const transform = (data = {}) => { diff --git a/packages/next/docs/components/Select.md b/packages/next/docs/components/Select.md index 45a0a8a8803..639397dd52a 100644 --- a/packages/next/docs/components/Select.md +++ b/packages/next/docs/components/Select.md @@ -54,7 +54,7 @@ import { Select, FormItem, FormButtonGroup, Submit } from '@formily/next' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -213,7 +213,7 @@ import { Select, FormItem, FormButtonGroup, Submit } from '@formily/next' import { createForm } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -358,7 +358,7 @@ import { Select, FormItem, FormButtonGroup, Submit } from '@formily/next' import { createForm, onFieldReact } from '@formily/core' import { FormProvider, Field } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const useAsyncDataSource = ( pattern: Formily.Core.Types.FormPathPattern, diff --git a/packages/next/docs/components/TreeSelect.md b/packages/next/docs/components/TreeSelect.md index faf4624745e..e658539dd52 100644 --- a/packages/next/docs/components/TreeSelect.md +++ b/packages/next/docs/components/TreeSelect.md @@ -99,7 +99,7 @@ import { import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -379,7 +379,7 @@ import { import { createForm, onFieldReact } from '@formily/core' import { FormProvider, createSchemaField } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const SchemaField = createSchemaField({ components: { @@ -638,7 +638,7 @@ import { import { createForm, onFieldReact } from '@formily/core' import { FormProvider, Field } from '@formily/react' import { LoadingOutlined } from '@ant-design/icons' -import { action } from 'mobx' +import { action } from '@formily/reactive' const useAsyncDataSource = ( pattern: Formily.Core.Types.FormPathPattern, diff --git a/packages/next/docs/components/index.md b/packages/next/docs/components/index.md index e772842ad79..a477136a4be 100644 --- a/packages/next/docs/components/index.md +++ b/packages/next/docs/components/index.md @@ -60,7 +60,7 @@ ## 安装 ```bash -$ npm install --save @alifd/next mobx mobx-react-lite moment +$ npm install --save @alifd/next moment $ npm install --save @formily/next @formily/react ``` diff --git a/packages/next/docs/index.md b/packages/next/docs/index.md index c768cdc3c35..cc7639a97d5 100644 --- a/packages/next/docs/index.md +++ b/packages/next/docs/index.md @@ -25,7 +25,7 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by sel ## 安装 ```bash -$ npm install --save @alifd/next mobx moment +$ npm install --save @alifd/next moment $ npm install --save @formily/core @formily/react @formily/next ``` diff --git a/packages/next/src/form-collapse/index.tsx b/packages/next/src/form-collapse/index.tsx index 623de70e210..672d4b03199 100644 --- a/packages/next/src/form-collapse/index.tsx +++ b/packages/next/src/form-collapse/index.tsx @@ -1,6 +1,6 @@ import React, { Fragment, useMemo } from 'react' import { Collapse, Badge } from '@alifd/next' -import { createModel } from '@formily/reactive' +import { model } from '@formily/reactive' import { CollapseProps, PanelProps as CollapsePanelProps, @@ -63,7 +63,7 @@ const usePanels = () => { } const createFormCollapse = (defaultActiveKeys?: ActiveKeys) => { - const formCollapse = createModel({ + const formCollapse = model({ activeKeys: defaultActiveKeys || [], setActiveKeys(keys: ActiveKeys) { formCollapse.activeKeys = keys diff --git a/packages/next/src/form-step/index.tsx b/packages/next/src/form-step/index.tsx index a9978ea1c48..fe26d1ad881 100644 --- a/packages/next/src/form-step/index.tsx +++ b/packages/next/src/form-step/index.tsx @@ -1,5 +1,5 @@ import React, { Fragment } from 'react' -import { createModel } from '@formily/reactive' +import { model } from '@formily/reactive' import cls from 'classnames' import { StepProps as StepsProps, @@ -96,7 +96,7 @@ const createFormStep = (defaultCurrent = 0): IFormStep => { } } - const formStep: IFormStep = createModel({ + const formStep: IFormStep = model({ connect(steps, field) { env.steps = steps env.form = field?.form diff --git a/packages/next/src/form-tab/index.tsx b/packages/next/src/form-tab/index.tsx index 3e8ea8a0acd..d1e2ecba0a2 100644 --- a/packages/next/src/form-tab/index.tsx +++ b/packages/next/src/form-tab/index.tsx @@ -1,6 +1,6 @@ import React, { Fragment, useMemo } from 'react' import { Tab as Tabs, Badge } from '@alifd/next' -import { createModel } from '@formily/reactive' +import { model } from '@formily/reactive' import { ItemProps as TabPaneProps, TabProps as TabsProps, @@ -54,7 +54,7 @@ const useTabs = () => { } const createFormTab = (defaultActiveKey?: string) => { - const formTab = createModel({ + const formTab = model({ activeKey: defaultActiveKey, setActiveKey(key: string) { formTab.activeKey = key diff --git a/packages/react/docs/api/shared/observer.md b/packages/react/docs/api/shared/observer.md index 0c0f9a82edc..cf5adc99268 100644 --- a/packages/react/docs/api/shared/observer.md +++ b/packages/react/docs/api/shared/observer.md @@ -2,4 +2,4 @@ ## 描述 -observer 是从[mobx-react-lite](https://mobx.js.org/react-integration.html)中导出的 observer,API 完全一致,这里不详细说明,使用 observer 主要是将组件支持响应式更新能力 +observer 是从[@formily/reactive-react](https://reactive.formilyjs.org)中导出的 observer,API 完全一致,这里不详细说明,使用 observer 主要是将组件支持响应式更新能力 diff --git a/packages/react/docs/index.md b/packages/react/docs/index.md index a781667d57c..2a39b7960f5 100644 --- a/packages/react/docs/index.md +++ b/packages/react/docs/index.md @@ -34,7 +34,6 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by sel ## 安装 ```bash -$ npm install --save mobx $ npm install --save @formily/core @formily/react ``` diff --git a/packages/reactive/src/__tests__/annotations.spec.ts b/packages/reactive/src/__tests__/annotations.spec.ts index 2de8c0b5c53..391b7eaf71b 100644 --- a/packages/reactive/src/__tests__/annotations.spec.ts +++ b/packages/reactive/src/__tests__/annotations.spec.ts @@ -1,4 +1,4 @@ -import { observable, batchable } from '../' +import { observable, action } from '../' import { autorun, reaction } from '../autorun' import { observe } from '../observe' import { isObservable } from '../shared' @@ -69,7 +69,7 @@ test('ref annotation', () => { test('action annotation', () => { const obs = observable({}) - const setData = batchable(() => { + const setData = action(() => { obs.aa = 123 obs.bb = 321 }) diff --git a/packages/reactive/src/__tests__/batch.spec.ts b/packages/reactive/src/__tests__/batch.spec.ts index 98ba5e47d31..fcb6a8a5d11 100644 --- a/packages/reactive/src/__tests__/batch.spec.ts +++ b/packages/reactive/src/__tests__/batch.spec.ts @@ -1,4 +1,4 @@ -import { observable, batchable, batch, autorun } from '..' +import { observable, action, batch, autorun } from '..' test('batch', () => { const obs = observable({ @@ -21,14 +21,14 @@ test('batch', () => { expect(handler).toBeCalledTimes(4) }) -test('batchable', () => { +test('action', () => { const obs = observable({ aa: { bb: 123, }, }) const handler = jest.fn() - const batch = batchable(() => { + const batch = action(() => { obs.aa.bb = 333 obs.aa.bb = 444 }) diff --git a/packages/reactive/src/annotations/observable.ts b/packages/reactive/src/annotations/observable.ts index 25643d3221e..fb61f133840 100644 --- a/packages/reactive/src/annotations/observable.ts +++ b/packages/reactive/src/annotations/observable.ts @@ -35,6 +35,7 @@ export const observable: IObservable = createAnnotation( value, }) store.value = value + if(oldValue === value) return runReactionsFromTargetKey({ target: target, key: key, diff --git a/packages/reactive/src/annotations/shallow.ts b/packages/reactive/src/annotations/shallow.ts index 681341020a1..0ada7578c99 100644 --- a/packages/reactive/src/annotations/shallow.ts +++ b/packages/reactive/src/annotations/shallow.ts @@ -34,6 +34,7 @@ export const shallow: IObservable = createAnnotation( shallow: true, }) store.value = value + if(oldValue === value) return runReactionsFromTargetKey({ target: target, key: key, diff --git a/packages/reactive/src/batch.ts b/packages/reactive/src/batch.ts index 6eb8d4dda6a..16b2c4ae81e 100644 --- a/packages/reactive/src/batch.ts +++ b/packages/reactive/src/batch.ts @@ -16,7 +16,7 @@ export const batch = (callback?: () => T) => { return result } -export const batchable = createAnnotation(({ target, key, value }) => { +export const action = createAnnotation(({ target, key, value }) => { const action = any>(callback?: T) => { return function (...args: Parameters): ReturnType { return batch(() => @@ -31,4 +31,4 @@ export const batchable = createAnnotation(({ target, key, value }) => { return action(value) }) -batch[MakeObservableSymbol] = batchable +batch[MakeObservableSymbol] = action diff --git a/packages/reactive/src/model.ts b/packages/reactive/src/model.ts index 07253dc361e..409a21b6d65 100644 --- a/packages/reactive/src/model.ts +++ b/packages/reactive/src/model.ts @@ -30,20 +30,17 @@ export function defineModel( }) } -export function createModel(target: Target) { - return defineModel( - target, - reduce( - target, - (buf, value, key) => { - if (isFn(value)) { - buf[key] = batch - } else { - buf[key] = observable - } - return buf - }, - {} - ) - ) +export function model(target: Target) { + const annotations = Object.keys(target || {}).reduce((buf, key) => { + const descriptor = Object.getOwnPropertyDescriptor(target, key) + if (descriptor && descriptor.get) { + buf[key] = observable.computed + } else if (isFn(target[key])) { + buf[key] = batch + } else { + buf[key] = observable + } + return buf + }, {}) + return defineModel(target, annotations) }