Open in new Tab
        import React from 'react';
import { Tabs, Input, Button, Table } from 'antd';
const TabPane = Tabs.TabPane;

import { vanex, start, Relation } from 'vanex';

const userModel = {
  name: 'userModel',
  data: {
    username: 'codefalling',
  },
  syncs: {
    setName(val) {
      this.username = val;
    },
  },
};

const detailModel = {
  name: 'detailModel',
  data: {
    fetchedData: {},
    isLoading: false,
    isDataOutDated: false,
  },
  effects: {
    async fetch(username) {
      const API = `https://api.github.com/users/${username}`;
      this.isLoading = true;
      const res = await fetch(API);
      const data = await res.json();
      this.isLoading = false;
      this.isDataOutDated = false;
      this.fetchedData = data;
    },
  },
  computed: {
    get dataSource() {
      if (this.fetchedData && this.fetchedData.login) {
        const data = this.fetchedData;
        return [
          {
            key: 1,
            name: data.name,
            avatar: data.avatar_url,
            followers: data.followers,
          },
        ];
      }
    },
  },
};

// 定义 Model 间的关联
const relation = new Relation();

relation.autorun(context => {
  if (context.userModel.username) {
    // context 相当于注入了所有的 Model,可以跨 Model 进行通信
    context.detailModel.isDataOutDated = true;
  }
});

@vanex('userModel')
class NameChanger extends React.Component {
  render() {
    const { userModel } = this;
    const { username } = userModel;
    return (
      <Input
        value={username}
        style={{width: '130px'}}
        onChange={e => userModel.setName(e.target.value)}
      />
    );
  }
}

// 同时注册两个 Model
@vanex('detailModel', 'userModel')
class DetailView extends React.Component {
  constructor() {
    super(...arguments);
    this.clickHandler = this.clickHandler.bind(this);
  }
  
  clickHandler(e) {
    this.detailModel.fetch(this.userModel.username);
  }
  
  componentDidMount() {
    this.detailModel.fetch(this.userModel.username);
  }
  
  render() {
    const { fetchedData, isLoading, dataSource, isDataOutDated } = this.detailModel;
    const columns = [
      {
        title: '用户名',
        dataIndex: 'name',
      },
      {
        title: '头像',
        dataIndex: 'avatar',
        render: (text) => <img style={{width: '80px'}} src={text}></img>
      },
      {
        title: 'followers',
        dataIndex: 'followers',
      },
    ];
    return (
      <div>
        <Button type="primary" loading={isLoading} onClick={this.clickHandler}>
          { isDataOutDated ? '用户名已改变,请点击重新获取用户信息' : '获取用户信息'}
        </Button>
        {dataSource
          ? <div>
              <h2>用户信息</h2>
              <Table columns={columns} dataSource={dataSource} />
            </div>
          : null}
      </div>
    );
  }
}

@vanex('userModel')
class ContainerComponent extends React.Component {
  render() {
    const { userModel } = this;
    return (
      <div>
        用户 ID:{userModel.username}
        <h1>UserModel</h1>
         <NameChanger />
        <h1>UserModel & DetailModel</h1>
        <DetailView />
      </div>
    );
  }
}

start({
  component: ContainerComponent,
  container: '#mountNode',
  models: {
    // 注册模型
    userModel,
    detailModel,
  },
  relation,
});

    
        @import 'antd/dist/antd.css';