结构

Vanex 中负责存储数据,同步/异步的数据操作,其结构如下:

const xxxModel = {
    name: 'xxxModel',
    data: {
        // 数据存放
        globalCount: 0,
        login: {
            abc: 'test'
        },
        ...
    },
    syncs: {
        // 所有的同步操作
        // 在组件中可以通过 this.xxxModel.loginResetAbc('A new Val') 调用
        loginResetAbc(arg) {
            this.login.abc = arg;
        },
        ...
    },
    effects: {
        // 所有的异步操作,必须是 async function
        // 在组件中可以通过 await this.xxxModel.loginFetch() 调用
        async loginFetch() {
            const data = await fetch(...);
            return data.xxx;
        }
        //...
    },
    computed: {
        // 响应式的计算值
        get nameWithCount() {
            // 当在组件中依赖了 nameWithCount 时,abc 或者 globalCount 改变时
            // 都会触发该值的重新计算并且触发组件重新 render
            return `${this.abc} - ${this.globalCount}`;
        }
        //...
    },
    autorun: {
        // 当依赖的值发生变动时被执行
        someName() {
            if (this.abc) {
                // abc 获得新的值时
                this.globalCount = this.globalCount + 1;
            }
        },
        // ...
    },
};

操作数据

上面我们可以看到,我们既可以在组件中直接操作数据,也可以在 Model 的 syncs/effects 中操作数据,但是我们更推荐在 Model 中操作数据。一方面是为了将操作数据的逻辑分离,另一方面 Vanex 针对 Model 中的数据操作做了优化,一个 sync 或者 一个 effect 中的所有数据操作只会触发一次重新渲染

注册

要使用一个 model,使用 Vanex 的 start 函数中注册。

import { start } from 'vanex';

start({
    component: App,
    container: '#root',
    models: {
        xxxModel,
        //... 其他 model
    }
});

在组件中使用

为了在组件中访问到 model,我们可以通过 @vanex API 来注入相应的依赖。

import { vanex } from 'vanex';

@vanex('xxxModel', 'yyyModel', ...)
class XComponent {
    render() {
        // 可以通过 `this.xxxModel` 访问注入的 xxxModel
        // 通过 `this.props.xxxModel` 也可以访问,但不推荐
        const { name, someSync } = this.xxxModel;
        return <div>
            <Button onClick={() => someSync('test')}>{name}</Button>
        </div>
    }
}

纯函数组件

由于纯函数组件没有 class 也没有 this,所以我们只注入到 props 中。

import { vanex } from 'vanex';

const PureComponent = vanex('xxxModel')(
    ({ xxxModel }) => <div>
        {xxxModel.name}
    </div>
);

原有的注入方法

你也可以使用 mobx-react 提供的注入方法,这种方式只注入到 props 中而不注入到 this。

相关的文档参见 https://github.com/mobxjs/mobx-react ,如果你有更复杂的需求可以考虑使用该 API。

import { inject, observer } from 'vanex';

@inject('xxxModel')
@observer
class XComponent {
    render() {
        // 这种方式只注入到 `this.props.xxxModel`
        const { name, someSync } = this.props.xxxModel;
        return <div>
            <Button onClick={() => someSync('test')}>{name}</Button>
        </div>
    }
}

Model 的拆分

通常我们推荐把不同模块的数据放在分开的 Model 中,然后一个组件注入一个或者多个 Model,下面是一个相对复杂的 Model 使用例子:

results matching ""

    No results matching ""