# 基础

# 脚手架快速上手

建议直接使用create-sula脚手架创建playground项目来了解和学习 sula。

# 环境准备

全局安装create-sula

# 阿里内网源
$ tnpm i -g create-sula

# yarn / npm / cnpm 外网
$ yarn global add create-sula

# 脚手架

创建项目目录

$ mkdir myapp && cd myapp
$ create-sula .

# 或者
$ create-sula myapp

# 或者直接选择模板
$ create-sula crud .

然后选择playground,使用smallfish构建。

? Select the boilerplate type (Use arrow keys)
❯ crud            - 🏡  (project) Create sula playground. 
  antd-pro-layout - 🏡  (project) Create sula admin with antd-pro-layout. 
  hello-world     - 🏡  (project) Create a hello-world sula project based on umi. 
  cooker          - 🏡  (project) Create sula cooker. 
  create-form     - 📋  (template) Create sula template create form. 
  search-table    - 📋  (template) Create sula template search table.

选择 crud 模板后需要选择构建工具

? Select the boilerplate type playground
? 选择构建工具
  umi
❯ @alipay/bigfish
  smallfish

启动项目

$ cd myapp
$ tnpm i
$ npm start

# 创建项目

create-sula内置多个项目模板,绝大部分场景直接选择 crud 模板即可。

# 创建模版

create-sula内置了 3 个与CRUD相关的模版

  1. @sula-template/creat-form:创建表单
  2. @sula-template/creat-wizard:创建分布表单
  3. @sula-template/search-table:查询表格

下面介绍如何在playground项目工程中新增模版,首先,看下 playground 的项目模板结构,

.
├── README.md
├── config
│   ├── config.js
│   ├── menu.js
│   ├── router
│   │   └── index.js
│   └── single.config.js
├── jsconfig.json
├── mock
│   ├── form.mock.js
│   ├── response.js
│   └── table.mock.js
├── package.json
└── src
    ├── global.js
    ├── layout
    │   ├── index.js
    │   └── index.less
    └── page
        ├── exception
        │   ├── 403.js
        │   └── 404.js
        └── playground
            ├── create.js
            ├── createForm.js
            ├── createWizard.js
            ├── manage.js
            └── searchTable.js

我们要在 src/page/ 创建目录 task,再通过 create-sula 生成 create-form 模板,

$ cd src/page
$ mkdir task
$ create-sula task
# 选择create-form模板

完成以上步骤后 src/page 的目录结构,

.
├── exception
│   ├── 403.js
│   └── 404.js
├── playground
│   ├── create.js
│   ├── createForm.js
│   ├── createWizard.js
│   ├── manage.js
│   └── searchTable.js
└── task
    └── createForm.js

接着我们需要将 task/createForm.js 与 /task/create 修改 config/router/index.js ,只需要依 playground 画 task 完成路由配置,

// 在routes数组中增加
{
  name: '新建任务',
  path: '/task/create',
  component: './task/createForm',
}

最后我们需要将 /task/create 路由设置到左导上,修改 config/menu.js

// 增加
{
    displayName: '任务',
    icon: 'profile',
    hasChildren: true,
    children: [
      {
        displayName: '新建任务',
        link: '/task/createForm',
        icon: 'plus-square',
      },
    ],
  },

这样就完成了任务模块的新建任务的创建。

# 快速配置模版

sulajs提供了以下模版组件,方便CRUD工程项目的快速创建。

# 查询表格

查询表格一般出现在CRUD页面的入口处,通过简单配置即可实现表单与表格联动页面。api 文档请查看search-table api

search-table

# 创建表单

一般使用在详情页、编辑页、创建页面等,带有页脚的表单页面,支持表单联动等配置。api 文档请查看create-form api

create-form

# 分步表单

分步表单,引导用户按照流程创建表单。api 文档请查看create-wizard

create-wizard

# 导航

# 导航接入

安装

$ tnpm install @sula/nav -S

使用

import Nav from "@sula/nav";

# 功能配置

# 导航配置

除 menus 和 routes 必须配置以外,其他都可选配。

nav.start({
  siderConfig: {
    menus: [ // 菜单信息,必填
      {
        displayName: "",
        icon: "api",
        children: [
          {
            displayName: "",
            icon: "",
            link: "",
          },
          {
              displayName: "",
              icon: "",
              children: [...]
          }
        ]
      }
    ]
  },

  routes: [], // 路由信息(项目路由配置信息)

  // 通过配置url地址方式切换请求
  userInfoUrl: "/ifcbuservice/getLoginUserInfo.json", // 获取登录信息地址
  logoutUrl: "/ifcbuservice/doLocalUserLogout.json",  // 登出请求地址
  topMenusUrl: "/gateway/webapi/menu", // 顶部导航数据地址
  loginUrl: "/ifcbuservice/login.htm", // 登录页面地址

  // 通过配置方法替换导航数据
  getUserInfo,
  getTopMenus,
  logout,

  // 用户鼠标移上下拉内容配置
  userInfoView,   // react节点信息
  userInfoViewData,

  // 显示开关配置
  topMenusVisible: true,
  breadcrumbVisible: true, // 是否显示面包屑

  // 配置导航扩展
  navLeftExtra, // 左侧扩展,传入react节点信息
  navRightExtra // 右侧扩展,传入react节点信息
});

# routes 配置

routes 配置主要用于面包屑数据获取和菜单匹配(菜单会优先使用 menus 信息进行匹配)
例:如当前页面地址为#/test/a/b,面包屑会显示[测试,测试a,测试ab]

[
  {
    name:'测试',
    path:'/test'
    routes: [
      {
        name:'测试a',
        path:'/test/a',
        routes: [
          {
            name:'测试ab',
            path:'/test/a/b',
          }
        ]
      }
    ]
  }
]

# 导航提供方法

// 1.修改面包屑
singleNav.updateBreadcrumb([{
  name:"",
  path:""
}]);

// 2.添加面包屑右侧扩展
singleNav.updateBreadcrumbExtraContent(content); //content可以为字符串或react节点  

# 接入buservice

  1. ifcriskmatrixus系统后台配置导航信息

    登陆ifcriskmatrixus系统,配置导航信息,新建appName,并配置对应的目录信息

    buservice导航配置

  2. 在项目中配置代理接口

    config.js中加入以下配置:

    proxy: {
      '/ifcbuservice': {
        target: 'http://ifcriskmatrixus-web-1.dev.alipay.net'  // 代理接口
      }
    }
    
  3. 请求导航数据

    src/layout/index.js中加入以下配置:

    fetch({
        url: '/ifcbuservice/getUserEnabledMenus.json?appName=admin', //这里需替换appName为配置的对应的appName名称
      }).then(val => {
        Nav.start({
          ..., // 导航配置见上方
        })
      });
    

# 请求

sulajs基于axios封装了请求方法,内置错误处理等功能。使用sula-fetch并根据接口规范开发接口,能大幅度减少前端代码量。

# sula-fetch

在项目中使用sula-fetch:

// 确保项目中引用了umi-plugin-sula
import { fetch } from '@sula/biz';

fetch({ url: '' }).then(res => { ... })

详情请参考请求插件

# 接口规范

接口定义准则: 数据格式在保持语义的情况下尽量扁平化

# 请求格式

请求方法 内容类型 适用场景
GET application/x-www-form/urlencoded 静态资源获取,如download
POST application/json 数据查询、数据增、删、改以及复杂的表单数据查询
POST multipart/form-data 图片等文件上传

一般情况下,表单类模版中发出的请求参数为表单值;查询表格的请求参数包括分页、过滤、排序信息等,如下所示:

{
  method: 'POST',
  params: {
    filters: { // 过滤信息
      [key: string]: any
    },
    sorter: { // 排序信息
      columnKey: string,
      order: 'ascend' | 'descend' | undefined,
    },
    current: number, // 当前页
    pageSize: number  // 每页条数
  }
}

# 响应格式

{
  code: number; // 响应状态码,可用于详细判断接口
  data: any; // 业务数据
  success: boolean; // 接口调用结果,可用于简单判断接口是否成功
  message: string; // 前端展示信息,多用于错误信息展示
  description: string; // 错误详细描述 for 开发排查问题
}

表单类模版中值、数据源的响应数据为表单值、数据源的格式;查询表格的响应数据分为两类:

  1. 有分页

    {
      data: {
        list: [{}], // 或 dataSource,
        current: number, // 当前页
        pageSize: number, // 每页条数
        total: number, // 总条数
      }
    }
    
  2. 无分页

    {
      data: [{}]
    }
    

# 校验

sula-form支持AntD Form中表单校验方式,同时支持sula-form自定义校验方式。

# 使用插件

sulajs以插件为核心,通过插件可以将所有配置转化为JSON,实现后端持久化存储。

在插件专栏里,可以查看sulajs所有内置插件,同时sulajs提供了用户自定义插件的能力,若官方插件不满足使用场景,可以自定义一个自己的插件使用。

插件可以分为以下几类:

# 渲染插件

渲染插件提供了表单输入控件、表格插件、按钮、文本、容器等插件化的能力,详细请查看渲染插件

示例:

// 文本输入控件插件
{
  render: 'input',
}

// 容器插件
{
  container: {
    type: 'card',
    props: { title: 'Title' }
  }
}

# 行为插件

行为插件提供点击元素后触发特定操作行为的能力,详细请查看行为插件

示例:

// 刷新表格
{
  action: 'refresh'
}

# 请求插件

请求插件用于向服务器发起请求,是sula内部formtable组件及模版内部请求相关的能力基础,详细请查看请求插件

示例:

{
  remoteDataSource: {
    url: '/api/list.json',
    method: 'post',
  }
}

# 表单关联插件

表单关联插件提供来表单级联控制的能力,支持 值、可见性、数据源、是否禁用四种类型级联控制,详细请查看表单关联插件

示例:

{
  dependency: {
    visible: { // 当type字段输入'fruit'或者'vegetables'时,可见 其余不可见
      relates: ['type'],
      inputs: [['fruit', 'vegetables']],
      output: true,
      defaultOutput: false,
    },
  }
}

# 校验插件

校验插件扩展了表单校验的能力,内置空格校验、字符串匹配校验,详细请查看校验插件

示例:

{
  rules: [
    { validator: 'whitespace' },
  ]
}

# 扩展的渲染插件

扩展的渲染插件提供复杂的插件,如可编辑表格。详细请查看扩展的渲染插件

umi-plugin-sula是sulajs提供的结合umi项目使用以提供更多配行为配置能力的插件,如路由能力、render + action能力,注册全局渲染插件能力等。详细请查看umi插件

示例:

{
  render: {
    type: 'textLink',
    text: 'jumpto',
    path: '/',
  }
}

# 结合umi使用

umi-plugin-sula 使得 sula + umi 有着更好的开发体验和效率提升。当然,umi-plugin-sula 也可以和基于 umi 内核的 bigfish、smallfish 等无缝结合。

在项目中结合umi-plugin-sula,我们会在Sula的组件及模板中提供部分action类型(如路由类型'route')及render+action类型(如图标跳转类型'iconLink')等能力,帮助用户通过配置快速使用

# 使用方式

示例:

// .umirc.js
export default {
  plugins: ['umi-plugin-sula'],
}

# 国际化

// .umirc.js
export default {
  plugins: [
    ['umi-plugin-sula', {
      locale: {
        default: 'en-US', // 默认为'en-US',可选'zh-CN'
        baseNavigator: false,
      }
    }]
  ],
}

建议搭配umi-plugin-locale使用

// .umirc.js
export default {
  plugins: [
    'umi-plugin-sula', // 会使用umi-plugin-locale中的lang
    ['umi-plugin-locale', {
      locale: {
        default: 'zh-CN',
        baseNavigator: false,
      }
    }]
  ],
}

如果是bigfish

// config/config.js
export default {
  plugins: [
    'umi-plugin-sula', // 会使用umi-plugin-locale中的lang
  ],
  locale: {
    enable: true,
    default: 'zh-CN',
    baseNavigator: false,
  }
}

如果需要支持多语言切换,则需要设置 useLocalStorage

// .umirc.js
export default {
  plugins: [
    ['umi-plugin-sula', {
      locale: {
        useLocalStorage: true,
      }
    }], // 会使用umi-plugin-locale中的lang
    ['umi-plugin-locale', {
      locale: {
        default: 'en-US',
        baseNavigator: false,
      }
    }]
  ],
}

切换语言

import { setLocale } from 'umi/locale';

function() {
  return <Button onClick={() => {
    setLocale('zh-CN'); // 切换为中文 or en-US
  }}>中文</Button>
}

# 路由插件

umi-plugin-sula 包含了所有与路由跳转相关的插件,引用了umi-plugin-sula,也就意味着你可以直接在项目代码中使用路由插件。

# action插件

示例:

{
  // route
  render: {
    type: 'button',
    action: {
      type: 'route',
      path: '/createTask',
      query: {id: 's001'},
    }
  }

  // back (history.goBack)
  render: {
    type: 'button',
    action: 'back'
  }
  // forward (history.goForward)
  render: {
    type: 'button',
    action: 'forward',
  }
}

# sula-biz(路由、请求)

import { history, fetch, upload } from '@sula/biz';

除了通过插件来使用路由、请求的能力外,umi-plugin-sula 还提供了代码级能力

# history

示例:

{
  // route
  render: {
    type: 'button',
    action: {
      type: 'route',
      path: '/createTask',
      query: {id: 's001'},
    }
  }

  // back (history.goBack)
  render: {
    type: 'button',
    action: 'back'
  }
  // forward (history.goForward)
  render: {
    type: 'button',
    action: 'forward',
  }
}

# fetch

示例:

import { fetch } from '@sula/biz';

fetch({
  url: '/v1/info',
  method: 'get',
  params: { name: 'sula' },
  convertParams: ({params}) => params,
  converter:({data}) => data,
}).then(res => res).catch(errorDesc => {});

# upload

示例:


import { upload } from '@sula/biz';

upload('/v1/upload', {
    file1: file, // file 支持数组,即批量场景
    // 上传文件以外的参数
    name: 'sula'
  }
).then(res => res);

# 换肤

// config/config.js 或 .umirc.js
export default {
  "theme": {
    "@primary-color": "#13c2c2"
  }
}

# 包引用

sula v0.1版本设计之初将包拆分成了多个以 @sula 命名的包,但这导致使用者需要了解他需要用哪些包,增加了使用成本。因此我们改为将这些包都通过 sula 这一个包来承载。

安装 sula

$ tnpm i -S sula;

当然 umi-plugin-sula 也是必须的。

# sula列表

以下包已放入sula中:

独立包 sula中的引用名
@sula/form Form, Field, FieldGroup
@sula/table Table, AntdTable
@sula/modalForm ModalForm
@sula/form-action FormAction
@sula/plugin-render Icon, Button, Tag, Badge, .....
@sula-template/create-form CreateForm
@sula-template/create-wizard CreateWizard
@sula-template/search-table SearchTable
@sula/biz fetch, download, upload, route, history
@sula/plugin-loader renderPlugin

例如:

import CreateForm from '@sula-template/create-form';

// 可以写为
import { CreateForm } from 'sula';

项目中的依赖可以简化为:

{
  "dependencies": {
    "sula": "^0.1.0",
    "umi-plugin-sula": "^0.1.0"
  }
}
Last Updated: 2020/3/18 下午2:22:48