时间飞逝,转眼三个月过去了,自己博客也没更新过什么~ 对不起,我怂了,怂了三个月没写博客。不是不想写,而是时间不是特别充足,很忙,也不知该如何写起。
- 一.企业文化
- 二.好的方面
- 三.不好的方面
- 四.初识UI库
- 1.新建运力管理菜单及其所有模块
- 2.实现司机信息页面基础表格
- 3.实现司机信息页面刷新
- 4.实现司机信息表格单行操作(查看、编辑、删除、复制、自定义)
- 5.实现司机信息新增、批量、自定义操作
- 6.实现司机信息模糊查询
- 7.实现司机信息表格列表显隐;新增、编辑表单页自定义
- 8.实现自定义配置
- 9.整理组件通用性及功能实现
- 10.分析核心组件BTable
一.企业文化
从我离职一家教育公司开始说起吧。记得当时那家公司的企业文化,简单的就三个字:容
、真
、思
。
我对这三个字的理解:
包容、宽容身边的人和事
;
真诚、真心地为公司负责
;
做事、完成项目时三思而后行,先思考再执行
。
说实话,在那家公司自己也做到了这三点。 离职的原因无非就两个,一个是没成长(你给不了公司什么了),第二个是没价值(公司给不了你什么了)。
后面入职了一家创业公司,它的企业文化,也很简单,就三个词:坚韧
、职业
、相信
。
我对这三个词的理解:
坚韧地对待工作上的每一次挑战
;
把自己变得更加专业
;
相信自己、相信团队
。
目前的我正在为这三点努力。只有当你认同公司的企业文化时,公司才会认同你。我在这家公司没有了以前先思考再执行
的做事风格,而变成了先执行再思考
,主要还是时间不够导致的。
二.好的方面
1.买车
6月份,喜提了自己人生的第一辆车
,别克suv,尽管它是二手的,但我算是成为了有车一族。
也为它贴上了我的信仰:蒙奇·D·路飞
,励志成为海贼王的男人:
2.拿毕业证
6月份,拿到了上海交通大学本科学历
。
牢记上海交通大学的校训:饮水思源,爱国荣校
。
三.不足的方面
最近不太顺心的点,可能就是工作上的事情
。因为还得花时间去适应新的企业文化、新的业务方向、新的团队、新的ui库....在创业公司,追求高效率,效率高还不能导致质量下降,确实是件不容易的事情。我就喜欢挑战,所以来了~
公司后台管理系统主要技术栈是:react+react hooks+uix(基于Ant Design)+mobx
。
下面主要想说下这边的ui库,基于Ant Design的二次封装的uix,思想挺不错的,非常值得参考
,就是需要时间去学习和揣摩其定义好的各种API,后面也会提及这样开发的优缺点。
首先看下核心组件BTable表格组件的分解图:
现在看不懂没关系,后面看完每个详细属性,回过头再看,会领悟该图的意义。
四.初识UI库
1.新建运力管理菜单及其所有模块
以新增运力模块举例,从下面原型图可知,该菜单下面有四个模块,分别是:承运人信息、车辆信息、司机信息、收款人信息。
1.新增运力管理根文件夹:
创建transport文件夹到workbench: /src/pages/workbench
2.在该文件夹下面创建子文件夹及文件:
目录结构说明:
transport 运力管理
├── styles 运力相关样式
├── model 运力相关弹框
├── summary 运力相关每个tab详情页面
├── info.tsx 运力相关某个模块主页面(多个)
├── info_summary.tsx 运力相关某个模块tabs总详情页面(多个)
├── config.tsx 运力相关公共配置文件
└── routes.ts 运力相关路由
3.逐个实现它们,完成对routes.ts的定义
第一步,声明Routes,即运力相关url:
// 工作台全局路由
export const Routes = {
...
// 运力管理
TransportRoot: '/work/transport/carrier',
TransportCarrier: '/work/transport/carrier/info',
TransportCarrierDetail: '/work/transport/carrier/detail',
TransportVehicle: '/work/transport/vehicle/info',
TransportVehicleDetail: '/work/transport/vehicle/detail',
TransportDriver: '/work/transport/driver/info',
TransportDriverDetail: '/work/transport/driver/detail',
TransportPayee: '/work/transport/payee/info',
TransportPayeeDetail: '/work/transport/carrier',
};
第二步,声明permissionOriginEnum,即一级菜单、二级菜单权限:
// 权限枚举
export const permissionOriginEnum = {
...
// 运力管理
M_ENT_CARRIER_MAIN: "LW_M_ENT_CARRIER_MAIN",
M_ENT_CARRIER_MAIN_TRANSPORTER: "LW_M_ENT_CARRIER_MAIN_TRANSPORTER",
M_ENT_CARRIER_MAIN_VEHICLE: "LW_M_ENT_CARRIER_MAIN_VEHICLE",
M_ENT_CARRIER_MAIN_DRIVER: "LW_M_ENT_CARRIER_MAIN_DRIVER",
M_ENT_CARRIER_MAIN_PAYEE: "LW_M_ENT_CARRIER_MAIN_PAYEE",
}
第三步,把每个模块的页面组件定义出来: 即承运人主页、详情页;车辆主页、详情页;司机主页、详情页;收款人主页、详情页。 carrier.tsx、carrierSummary.tsx、vehicle.tsx、vehicleSummary.tsx、 driver.tsx、driverSummary.tsx、payee.tsx、payeeSummary.tsx。
import React from "react"
function Carrier() {
return (
<div>Carrier</div>
)
}
export default Carrier
第四步,把前面声明过的路由、权限、组件全部用到,完成对routes.ts的定义:
import { RouteVo } from "@bee/uix/typings"
import { lazy } from "react"
import { Routes } from "@/assets/config"
import { permissionOriginEnum } from "@/assets/config"
const carrier = lazy(() => import(/* webpackChunkName: "transport" */ "./carrier"))
const carrier_summary = lazy(() => import(/* webpackChunkName: "transport" */ "./carrierSummary"))
const vehicle = lazy(() => import(/* webpackChunkName: "transport" */ "./vehicle"))
const vehicle_summary = lazy(() => import(/* webpackChunkName: "transport" */ "./vehicleSummary"))
const driver = lazy(() => import(/* webpackChunkName: "transport" */ "./driver"))
const driver_summary = lazy(() => import(/* webpackChunkName: "transport" */ "./driverSummary"))
const payee = lazy(() => import(/* webpackChunkName: "transport" */ "./payee"))
const payee_summary = lazy(() => import(/* webpackChunkName: "transport" */ "./payeeSummary"));
export const transportRoutes: Array<RouteVo> = [
{
icon: "yunshu",
title: "运力管理",
path: Routes.TransportRoot,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN,
children: [
{
icon: "invoice_title",
title: "承运人信息",
component: carrier,
path: Routes.TransportCarrier,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_TRANSPORTER,
},
{
hide: true,
icon: "invoice_title",
title: "承运人详情",
component: carrier_summary,
path: Routes.TransportCarrierDetail,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_TRANSPORTER,
},
{
icon: "vehicle",
title: "车辆信息",
component: vehicle,
path: Routes.TransportVehicle,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_VEHICLE,
},
{
hide: true,
icon: "vehicle",
title: "车辆详情",
component: vehicle_summary,
path: Routes.TransportVehicleDetail,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_VEHICLE,
},
{
icon: "driver",
title: "司机信息",
component: driver,
path: Routes.TransportDriver,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_DRIVER,
},
{
hide: true,
icon: "driver",
title: "司机详情",
component: driver_summary,
path: Routes.TransportDriverDetail,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_DRIVER,
},
{
icon: "shoukuan",
title: "收款人信息",
component: payee,
path: Routes.TransportPayee,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_PAYEE,
},
{
hide: true,
icon: "shoukuan",
title: "收款人详情",
component: payee_summary,
path: Routes.TransportPayeeDetail,
permission: permissionOriginEnum.M_ENT_CARRIER_MAIN_PAYEE,
},
],
},
]
最后渲染成功:
目录结构发生的变化:
2.实现司机信息页面基础表格
时间有限,我就以运力管理其中的一个模块,司机信息模块来举例说明
。
实现table的分页(切换上一页、下一页、跳页)、每页展示多少条(默认20条)、显示共多少条,刷新当前列表。
这四个table表格的基本功能,仅用简单的三个属性就能实现!它们分别是:title
、url
、fields
。
先看效果:
再看实现:
import React from "react"
import { BTable } from "@bee/uix"
function Driver() {
return (
<BTable
title="司机信息"
url="/logistics/web/enterprise/carrier/driver/findPage"
fields={[{...}]}
/>
)
}
export default Driver
title即表格唯一标识符,表格名称
;
url即表格分页请求接口
;
fields即需要展示的字段
。(与接口字段一致)
下面是fields={[{...}]}的具体配置:
fields={[
{
width: 70,
title: "序号",
dataIndex: "serialNumber",
render: (text, record, index) => <span>{index + 1}</span>,
},
{
width: 70,
title: 'ID',
dataIndex: 'id',
render: (text) => <span>{text || '--'}</span>,
},
{
width: 120,
title: '司机姓名',
dataIndex: 'name',
render: (text) => <span>{text || '--'}</span>,
}, {
width: 140,
title: '手机号',
dataIndex: 'mobileNo',
render: (text) => <span>{text || '--'}</span>,
}, {
width: 200,
title: "身份证号",
dataIndex: "idCardNo",
render: (text) => <span>{text || '--'}</span>,
}, {
width: 200,
title: "身份证地址",
dataIndex: "idCardAddress",
render: (text) => <span>{text || '--'}</span>,
}, {
width: 200,
title: "驾驶证号",
dataIndex: "driverLicenseNo",
render: (text) => <span>{text || '--'}</span>,
}]}
3.实现司机信息页面刷新
通过注入的refreshIdx
变量自增1,去实现当前页面的刷新。
先看效果:
再看实现:
import React, { useEffect, useRef } from "react"
import { BTable } from "@bee/uix"
import { TableHooks } from "@bee/uix/typings"
function Driver({ refreshIdx = 0 }) {
const hooks = useRef<TableHooks>(null);
useEffect(() => {
if (!refreshIdx) return;
hooks.current && hooks.current.refresh();
}, [refreshIdx]);
return (
<BTable
title="司机信息"
url="/logistics/web/enterprise/carrier/driver/findPage"
fields={[{...}]}
onTableHooks={_hooks => hooks.current = _hooks}
/>
)
}
export default Driver
4.实现司机信息表格单行操作(查看、编辑、删除、复制、自定义)
实现table的单行的复制、编辑、删除,通过简单的配置即可实现,也可以自定义单行操作,比如:查看日志。
通过配置hasRowOperate
去显隐操作、detail
去设置详情接口、rowFuncs
去实现自定义单行操作。
先看效果:
再看实现:
import React, { useEffect, useRef } from "react"
import { BTable, bTableFuncConfig } from "@bee/uix"
import { TableHooks } from "@bee/uix/typings"
import { transportDriverApis } from "@/api/transport.api";
function Driver({ refreshIdx = 0 }) {
...
return (
<BTable
...
url={transportDriverApis.list}
hasRowOperate={true}
detail={
{
key: "id",
url: transportDriverApis.detail,
}
}
rowFuncs={[{...}]}
/>
)
}
export default Driver
下面是rowFuncs={[{...}]}的具体配置:
rowFuncs={
[
{
width: 50,
title: '查看',
method: bTableFuncConfig.extend,
render: record => (<BPopover
content={"查看"}
key={"set-permission"}
info={
<FIcon
size={17}
className="details"
name="l-details"
onClick={() => {
hooks.current.showDetail(record)
}}
/>
}
/>),
},
{
width: 50,
title: '编辑',
icon: commonTableIcons.edit(),
url: transportDriverApis.edit,
method: bTableFuncConfig.edit,
},
{
width: 50,
title: "删除",
icon: commonTableIcons.delete(),
url: transportDriverApis.delete,
method: bTableFuncConfig.delete
},
{
width: 50,
title: '复制',
icon: commonTableIcons.copy(),
url: transportDriverApis.add,
method: bTableFuncConfig.copy,
beforeStart: (row, config, callback) => enableTableFields(row, config, callback)
},
{
width: 50,
title: "日志",
method: bTableFuncConfig.extend,
render: record => <TableViewLog key={"tableViewLog"} operationEntityId={record.id} operationEntityType={'EnterpriseDriver'} />,
},
]
}
5.实现司机信息新增、批量、自定义操作
实现table的新增、批量删除、导入、导出,通过简单的配置即可实现,也可以自定义操作按钮。
通过配置isSelect
去显隐表格左侧选择按钮、isSelectMultiple
去定义左侧选择按钮是单选还是多选,batchFuncs
去实现自定义操作。
先看效果:
再看实现:
import React, { useEffect, useRef } from "react"
import { BTable, bTableFuncConfig } from "@bee/uix"
import { TableHooks } from "@bee/uix/typings"
import { transportDriverApis } from "@/api/transport.api";
function Driver({ refreshIdx = 0 }) {
...
return (
<BTable
...
url={transportDriverApis.list}
isSelect={true}
isSelectMultiple={true}
batchFuncs={[{...}]}
/>
)
}
export default Driver
下面是batchFuncs={[{...}]}的具体配置:
batchFuncs={[
{
url: transportDriverApis.add,
label: "新增",
method: bTableFuncConfig.add,
},
{
url: transportDriverApis.batchOperate,
label: "批量删除",
method: bTableFuncConfig.batchDelete,
query: { type: 'delete' },
},
{
url: transportDriverApis.import,
label: "导入",
method: bTableFuncConfig.import,
},
{
url: transportDriverApis.export,
label: "导出",
method: bTableFuncConfig.export,
},
{
url: transportDriverApis.batchOperate,
label: "批量禁用",
method: bTableFuncConfig.part,
query: { type: 'disabled' },
},
{
method: bTableFuncConfig.extend,
render: row => (
<Button
key={"extend-add"}
icon={commonTableIcons.add}
onClick={() => {
alert('自定义操作')
}}>
自定义操作
</Button>
),
}
]}
目前可以公共使用的属性:
// batchFuncs or rowFuncs 公共拓展方法属性
export const bTableFuncConfig = {
add: "add", // 新增
edit: "edit", // 编辑
copy: "copy", // 复制
delete: "delete", // 单条删除
batchDelete: "batchDelete", // 批量删除
part: "part", // 批量更新
import: "import", // 导入
export: "export", // 导出
extend: "extend", // 自定义操作
}
6.实现司机信息模糊查询
实现模糊查询,一般都是挨个写表单组件去实现,但这个是通过fields属性动态生成的。
通过在fields里面配置isFilter
去显隐表单查询组件、filterSort
去定义查询组件从左到右的顺序。
isFilter设置为ture的效果,默认和表单的字段倒序排放:
filterSort设置为1、2、3...的效果,按照1、2、3的顺序排放:
下面是fields={[{...}]}的具体配置:
fields={[
{
width: 70,
title: "序号",
dataIndex: "serialNumber",
render: (text, record, index) => <span>{index + 1}</span>,
},
{
width: 70,
title: 'ID',
dataIndex: 'id',
render: (text) => <span>{text || '--'}</span>,
},
{
width: 120,
title: '司机姓名',
dataIndex: 'name',
render: (text) => <span>{text || '--'}</span>,
isFilter: true,
filterSort: 1,
}, {
width: 140,
title: '手机号',
dataIndex: 'mobileNo',
render: (text) => <span>{text || '--'}</span>,
isFilter: true,
filterSort: 2,
}, {
width: 200,
title: "身份证号",
dataIndex: "idCardNo",
render: (text) => <span>{text || '--'}</span>,
isFilter: true,
filterSort: 3,
}, {
width: 200,
title: "身份证地址",
dataIndex: "idCardAddress",
render: (text) => <span>{text || '--'}</span>,
isFilter: true,
filterSort: 4,
}, {
width: 200,
title: "驾驶证号",
dataIndex: "driverLicenseNo",
render: (text) => <span>{text || '--'}</span>,
isFilter: true,
filterSort: 5,
}]}
7.实现司机信息表格列表显隐;新增、编辑表单页自定义
表单生成出来,默认都是input。 但是我们可以继续设置当前字段使用的表单组件是input、select、img或其他,也可以设置当前字段是否为必填项、字段是否需要显隐到表单...
1.显隐控制:isHide、isFilter、isReadonly
isHide:true,表格字段隐藏
想把序号、ID从表格中隐藏:
[{
width: 70,
title: "序号",
dataIndex: "serialNumber",
render: (text, record, index) => <span>{index + 1}</span>,
isHide: true,
},
{
width: 70,
title: 'ID',
dataIndex: 'id',
render: (text) => <span>{text || '--'}</span>,
isHide: true,
}]
isFilter:true,模糊查询字段显示
想把司机姓名这个条件去掉:
[{
width: 120,
title: '司机姓名',
dataIndex: 'name',
render: (text) => <span>{text || '--'}</span>,
// isFilter: true,
// filterSort: 1,
}]
isReadonly:true,表单添加、复制、编辑弹框字段隐藏
想把序号、ID从表单中隐藏:
[{
width: 70,
title: "序号",
dataIndex: "serialNumber",
render: (text, record, index) => <span>{index + 1}</span>,
isHide: true,
isReadonly: true,
},
{
width: 70,
title: 'ID',
dataIndex: 'id',
render: (text) => <span>{text || '--'}</span>,
isHide: true,
isReadonly: true,
}]
最终效果:
2.特殊fields值
fields除了能够根据接口返回的字段返回响应的值外,还有以下几个用法。
1.序号
{
width: 70,
title: "序号",
dataIndex: "serialNumber",
isReadonly: true,
render: (text, record, index) => <span>{index + 1}</span>,
}
2.使用表单行组件
{
dataIndex: "licenseTime",
title: "驾驶证有效期",
placeholder: ["生效时间", "失效时间"],
input: bTableInputConfig.daterange,
filterProps: ["licenseStartTime", "licenseEndTime"],
isHide: true,
}
看驾驶证有效期,不是普通input,而是组件daterange。
目前可以公共使用的组件:
export const bTableInputConfig = {
divide: "divide", // 分隔
text: "text", // 普通input(默认值)
number: "number", // 数量input
switch: "switch", // 判断是或否
radio: "radio", // 单选
money: "money", // 钱input
percent: "percent", // 百分比input
tonnage: "tonnage", // 吨input
select: "select", // 下拉选择
selectasync: "select-async", // 下拉异步选择
date: "date", // 日期(年月日)
daterange: "daterange", // 日期范围(年月日)
datetime: "datetime", // 时间(年月日时分秒)
datetimerange: "datetimerange", // 时间范围(年月日时分秒)
json: "json", // 转出json字符串input
textarea: "textarea", // 多行文本框input
image: "image", // 图片
ocr: "ocr", // 图片识别
selectmap: "selectmap", // 地图选址
selectAddress: "selectAddress", //地址级联选择
extend: "extend", // 自定义拓展
}
3.自定义表单行
{
dataIndex: "tip",
title: "提示",
isHide: true,
input: bTableInputConfig.extend,
inputRender: text => <span style={{color:'red'}}>司机不能重复</span>
}
看最后一个,只是个简单提示:司机不能重复。
8.实现自定义配置
该功能具体指的是可以通过穿梭框对筛选条件
、列表显示
、列表明细显示
、导出显示
、明细导出显示
的字段进行显示和隐藏。
以列表显示举例,先看效果:
再看实现:
import FTableConfig from "@/features/workbench/TableConfig"
// 原来的司机信息组件
function Driver() {...}
// 外面包的自定义配置组件
function CustomDriver() {
const [configVisible, setConfigVisible] = useState(false);
const hooks = useRef<TableHooks>(null);
return <FTableConfig
title={"司机信息自定义配置"}
visible={configVisible}
fields={fields}
config={{ type: "LOGISTICS_ENTERPRISE_DRIVER", ...tableConfigApis }}
onClose={() => setConfigVisible(false)}
onAfter={() => hooks.current && hooks.current.refresh()}
table={fields => <Driver fields={fields} setConfigVisible={setConfigVisible} />}
/>
}
export default CustomDriver
9.整理组件通用性及功能实现
熟练并掌握其属性及API,开发效率不快都难~
1.功能实现及对应所需字段:
| 功能实现 | 所需字段 | 设置值 | | :----: | :----:| :----: | | 页面刷新 | refreshIdx | - | | 表格 | title、url、fields | - | | 表格单行操作 | hasRowOperate、detail、rowFuncs | true | | 表格批量操作 | isSelect、isSelectMultiple、batchFuncs | true | | 表格模糊查询 | isFilter、filterSort | true | | 表格字段隐藏 | isHide | true | | 表单字段隐藏 | isReadonly | true |
2.实现的公共弹框逻辑,基础的共8个:
| 功能实现 | 所需字段 | | :----: | :----:| | 新增 | add | | 编辑 | edit | | 删除 | delete | | 批量删除 | batchDelete | | 批量更新 | part | | 复制 | copy | | 导入 | import | | 导出 | export | | 功能扩展 | extend |
3.实现的公共表单组件,基础的共20个:
| 所需字段 | 功能实现 | 基于antd组件 |
| :----: | :----:| :----:|
| text | 输入框(普通) | <Input type="text" />
|
| money | 输入框(金钱) | <Input type="text" />
|
| tonnage | 输入框(吨数) | <Input type="text" />
|
| percent | 输入框(百分比) | <Input type="text" />
|
| number | 输入框(数量) | <Input type="text" />
|
| textarea | 输入框(多行) | <Input.TextArea />
|
| json | 输入框(转json字符串) | <Input.TextArea />
|
| switch | 开关 | <Switch />
|
| radio | 单选 | <Radio>Radio</Radio>
|
| date | 日期选择 | <DatePicker />
|
| datetime | 时间选择 | <DatePicker />
|
| daterange | 日期范围选择 | <DatePicker.RangePicker />
|
| datetimerange | 时间范围选择 | <DatePicker.RangePicker />
|
| select | 下拉选择(同步) | <Select />
|
| selectasync | 下拉选择(异步) | <Select />
|
| selectmap | 地图选址 | Input、Popover、Select、Spin 、高德地图web
|
| selectAddress | 地址级联选择 | <Cascader/>
|
| image | 图片相关 | Upload、message
|
| ocr | 图片识别相关 | Carousel、Button
|
| isDivide | 分隔 | Col span
|
10.分析核心组件BTable
只需要写配置文件,就能实现整个报表的基本功能,不得不说封装的ui库很强。 BTable分解示意图:
可以发现,它把一个常见的表格页面,按照业务功能分解成对应组件
,可以理解成业务组件
,然后业务组件又是基于UI组件封装
而成。
页面表格列头需要动态生成,于是封装了自定义设置组件FTableConfig
;
页面表格筛选查询需要动态生成,于是封装了顶部筛选组件BFilter
;
页面表格需要批量、自定义按钮操作,于是有了由多个Button按钮组成的批量操作区
;
页面表格需要主体和分页,于是有了由Table和Pagination组成的表格区
;
页面表格需要进行单行操作,于是有了由Drawer详情页
、BModal + BForm组成的弹框
、BModal + BConfirm组成的确认弹框
。
BFilter组件和BForm组件都是颗粒度比较小的组件,小到输入框、上传按钮、单选、多选、日期选择、下拉选择、级联选择...因此完全可以复用它们。
最后,问几个问题,这么搭ui库的意义?提升页面性能?或是其他目的?
按照这样写代码,究竟有哪些优势和劣势呢?
先说意义:
我认为这么搭最大的意义在于能快速生成统一交互、风格的页面
。
8个基础的弹框逻辑+20个基础的表单组件,根据业务配置不同的弹框逻辑+组件,后面按照这样的配置玩法,一天出10个这样的页面都不是事!
再来说下它的优势和劣势: 优势: 1.统一开发,新人直接按照这样的配置去写就行; 2.支持复用,不同项目可以共用这一套ui库; 3.快速生成页面。
劣势: 1.学习成本高,需系统地学习才能快速开发 由于文档的不即使更新、还有demo的不完善,想快速上手很难,得靠自己去理解。其次,如果不去看ui库内部的实现逻辑,你都不知道干了啥事情。
2.不可随antd一起升级UI库 由于ui库是在antd ui库基础上进行封装的,比如当时封装ui库时依赖antd4.0.0,随着时间的飞逝,antd升级到4.16.12后,难免会出现新特性及新api用不了的情况。 这时即使强升级antd到最新,也会带来很大的风险,毕竟很多之前的老特性没了。 之前在老项目里用到的老特性去实现的业务,可能就会出问题。 还有老项目里为了实现业务,做出的各种骚操作,在一升级后,也可能会出问题。
3.不能更改交互,交互一更改,开发效率直线下降 目前都是在一个页面弹各种框实现的各种业务,那如果新增、编辑、不是弹框,而是跳页面,又该如何实现呢? 目前的方法就两个: 一是挨去实现表单页面,重新开始绘制表单;(布局、样式可以自定义) 二是使用BForm去动态生成表单;(布局、样式自定义很难)
后面会写一篇文章,分析其ui库实现原理及具体怎么封装的,敬请期待。