ice-lab / icejs

仓库迁移至:https://github.com/alibaba/ice
https://ice.work/docs/guide/intro
MIT License
75 stars 16 forks source link

[RFC] icejs+ #156

Closed alvinhui closed 4 years ago

alvinhui commented 4 years ago

是什么?

icejs+ 是一个面向中后台领域强约束框架,是 icejs 的超集。

icejs+ 对 icejs 没有任何不兼容性的改动。

为什么?

怎么做?

API 设计

目录结构

├── .ice/                           # 运行时生成的临时目录
├── .editorconfig
├── .gitignore
├── tsconfig.json
├── package.json
├── README.md
├── build/                          # 构建产物目录
├── mock/                           # 模拟数据目录
│   └── index.ts
├── public/                         # 静态资源
└── src/                            # 源码
    ├── app.ts                      # 启动文件(可选)
    ├── configs.ts                   # 常量配置
    ├── utils.ts                    # 工具方法
    ├── global.scss                 # 全局样式
    ├── variables.scss              # 样式变量
    ├── routes.ts                   # 路由配置
    ├── layouts                     # 布局组件目录
    │   └── BasicLayout
    │       ├── components          # 布局子组件目录
    │       │   └── Foo
    │       │       ├── model.ts    # 模型
    │       │       └── index.rml   # 入口
    │       ├── model.ts
    │       └── index.rml           # 布局组件入口
    ├── pages                       # 页面组件目录
    │   └── Dashboard
    │       ├── components          # 页面子组件目录
    │       │   └── Foo
    │       │       ├── model.ts
    │       │       └── index.rml
    │       ├── models              # 页面模型目录
    │       │   ├── foo.ts
    │       │   └── index.ts
    │       └── index.rml           # 页面组件入口
    ├── components                  # 应用组件
    │   └── Foo
    │        ├── model.ts
    │        └── index.rml
    ├── services                    # 应用服务
    │   ├── foo.ts
    │   └── test.ts
    └── models                      # 应用模型
        └── foo.ts

遗留问题:

  • services 和 mock 的结合?
  • services 和 model 的结合?

package.json

{
  "name": "icejs",
  "version": "0.1.0",
  "dependencies": {
    "build-preset-plus": "^0.1.0",
    "@alifd/next": "^1.19.4"
  },
  "devDependencies": {
    "ice.js": "^1.0.0"
  },
  "scripts": {
    "start": "icejs start",
    "build": "icejs build",
    "lint": "icejs lint"
  }
}

index.rml

<script>
import PropTypes from 'prop-types';
import { 
  useRef, // react 内置 hooks
  useMount, useUnmount, useUpdate, // react 生命周期的 hooks
  useHistory, useLocation, // react-router 的 hooks
} from 'ice';
import { 
  model, // 组件模型
  services,
} from '$';
import config from '@/config'; // 应用常量
import moment from 'moment'; // 三方包

const Component = function(props) {
  const [state, actions] = model.useValue(); // useState/useActions/useEffectsState
  const field = Field.useField();
  const history = useHistory();
  const location = useLocation();
  const ref = useRef(null);
  const { status, data, error, request } = services.useRequest('todos');

  useMount(() => {
  });

  function handleClick() {
  }

  // 模板的变量全部来自函数的返回
  return {
    state, // 状态
    actions, // 动作
    events: { // 事件绑定
      handleClick
    },

    // 全局信息
    utils: {
      moment,
    },
    config,
    history,
    location,

    // 其他
    field,
    ref,
  };
};

Component.propTypes = {
  title: PropTypes.string,
};

export default Component;
</script>

<style lang="scss">
.wrap {
  .loading {
  }
}
</style>

<import default="GlobalComponent" from="@/components/Global" /> <!-- 应用组件 -->
<import default="OtherComponent" from="./Other" /> <!-- 同级组件 -->
<import Loading="Loading" Input="Input" Field="Field" Form="Form" from="@alife/next" /> <!-- 基础组件 -->
<import default="Qrcode" from="@icedesign/qrcode" /> <!-- 三方组件 -->

<div className="wrap">
  <h2>{props.title}</h2>
  <div x-if={condition}>
    <Loading className="loading" />
  </div>
  <div x-else>
    <!-- 事件绑定到行内 -->
    <div
      x-for={item in state.todos}
      onClick={function() {
        actions.addTodo();
      }}
    >
      {item.title}
    </div>
    <GlobalComponent />
    <OtherComponent />
    <Form field={field}>
      <Input ref={ref} />
    </Form>
  </div>
</div>

模板语法参考:https://github.com/ReactML/ReactML

model

https://github.com/ice-lab/icestore/blob/master/docs/api.md

import { services } from 'ice';

export default {
  state: {
    todos: []
  },
  reducers: {
    addTodo(prevState, todo) {
    },
    refresh() {
      const data = await services.todos.request(); // 调用数据源
    }
  },
};

service

https://github.com/ice-lab/icejs/issues/100

export default {
  "type": "json",
  "options": {
    "method": "GET",
    "params": {},
    "isCors": 1,
    "uri": "//todos.com"
  },
  "description": "任务列表",
  "dataHandler": function(data, error) {
    return data;
  },
};

方案

chenbin92 commented 4 years ago

已沟通确认