# 基础
# 脚手架快速上手
建议直接使用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
相关的模版
- @sula-template/creat-form:创建表单
- @sula-template/creat-wizard:创建分布表单
- @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
工程项目的快速创建。
- search-table 查询表格
- create-form 创建表单
- create-wizard 分步表单
# 查询表格
查询表格一般出现在CRUD
页面的入口处,通过简单配置即可实现表单与表格联动页面。api 文档请查看search-table api
# 创建表单
一般使用在详情页、编辑页、创建页面等,带有页脚的表单页面,支持表单联动等配置。api 文档请查看create-form api
# 分步表单
分步表单,引导用户按照流程创建表单。api 文档请查看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
ifcriskmatrixus系统后台配置导航信息
登陆ifcriskmatrixus系统,配置导航信息,新建appName,并配置对应的目录信息
在项目中配置代理接口
config.js中加入以下配置:
proxy: { '/ifcbuservice': { target: 'http://ifcriskmatrixus-web-1.dev.alipay.net' // 代理接口 } }
请求导航数据
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 开发排查问题
}
表单类模版中值、数据源的响应数据为表单值、数据源的格式;查询表格的响应数据分为两类:
有分页
{ data: { list: [{}], // 或 dataSource, current: number, // 当前页 pageSize: number, // 每页条数 total: number, // 总条数 } }
无分页
{ data: [{}] }
# 校验
sula-form
支持AntD Form中表单校验方式,同时支持sula-form
的自定义校验方式。
# 使用插件
sulajs
以插件为核心,通过插件可以将所有配置转化为JSON,实现后端持久化存储。
在插件专栏里,可以查看sulajs
所有内置插件,同时sulajs
提供了用户自定义插件的能力,若官方插件不满足使用场景,可以自定义一个自己的插件使用。
插件可以分为以下几类:
# 渲染插件
渲染插件提供了表单输入控件、表格插件、按钮、文本、容器等插件化的能力,详细请查看渲染插件
示例:
// 文本输入控件插件
{
render: 'input',
}
// 容器插件
{
container: {
type: 'card',
props: { title: 'Title' }
}
}
# 行为插件
行为插件提供点击元素后触发特定操作行为的能力,详细请查看行为插件
示例:
// 刷新表格
{
action: 'refresh'
}
# 请求插件
请求插件用于向服务器发起请求,是sula内部form
和table
组件及模版内部请求相关的能力基础,详细请查看请求插件
示例:
{
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"
}
}
FAQ →