高级特性
start() 运行时服务注入
hook.start(injectServices?) 允许将任意服务注入到 Jiess 上下文中,供所有组件通过 this.jiess 访问。
标准注入模式
javascript
const jiess = hook.start({
$page() { // 注入路由和 Store
const store = useStore();
const route = useRoute();
const router = useRouter();
return { store, route, router };
},
$recycle: new RecycleBin(), // 注入回收站
$customApi: new CustomApiService(), // 注入自定义服务
});
// 组件中使用
$JiessTable({
render(midder) {
this.jiess.$page.store.dispatch('fetchUserInfo');
this.jiess.$page.router.push('/dashboard');
this.jiess.$customApi.doSomething();
},
});注入机制
| 注入 key | 值类型 | 创建时机 | 同一 key 多次注入 |
|---|---|---|---|
$xxx(函数) | Function | 每次路由切换时调用 | 覆盖上一次结果 |
$xxx(对象) | Object/Class | start() 时创建一次 | 不覆盖(首次创建后缓存) |
javascript
// 注入函数:每次路由切换时重建
const jiess = hook.start({
$page() { return { store: useStore(), route: useRoute() }; },
});
// 注入对象:全局单例
const jiess = hook.start({
$myService: new MyService(),
});JiessMidder —— 事件总线
JiessMidder(原名 Midder)是 @jiess/utils 中的发布-订阅事件系统,在 Jiess Plus 中被广泛用于组件间通信。
基础用法
javascript
import { Midder } from '@jiess/utils';
const midder = new Midder(jiess, 'my-event');
// 订阅
midder.on((data) => {
console.log('收到事件:', data);
});
// 发布
midder.emit({ message: 'hello' });
// 移除
midder.off(handler);在 Jiess Plus 中的使用
javascript
$JiessTable({
render(midder) {
// Jiess 内部已创建多个 midder 实例:
// this.midder → 当前组件的事件总线
// midder.listManger → 列表数据管理
// midder.pagerManger → 分页管理
// midder.searchManger → 搜索管理
// 监听分页变化
this.midder.on('pageChange', ({ currentPage, pageSize }) => {
console.log('分页变化:', currentPage, pageSize);
});
// 广播给兄弟组件
this.midder.emit('refresh');
},
});子类化——MidderSdk 模式
大型项目中,推荐继承 Midder 封装业务逻辑:
javascript
import Midder from '@jiess/utils/midder';
class MidderSdk extends Midder {
static quickComponents = {};
constructor(jiess) {
super(jiess, 'MyAppMidder', 'no-store'); // no-store = 不缓存
}
static async login(values) {
const result = await api.login(values);
sessionStorage.setItem('CSRF_TOKEN', result.csrfToken);
return result;
}
static registerToJiess(jiess) {
jiess.midderSdk = new MidderSdk(jiess);
}
}$JiessFlow —— 流程引擎
@jiess/plus 内建对 JiessFlow 流程引擎的支持,用于审批流程、任务流转。
页面配置
javascript
$Layout({
jiessFlow: {
taskMark: 'main-xxx', // 流程任务标识
pageType: 2, // 页面类型:1=发起 / 2=审批 / 3=抄送
label: '请假审批',
},
children: {
$JiessTable({
action: '/api/approvals',
$fields: [
{ $label: '申请人', $name: 'applicant' },
{ $label: '请假天数', $name: 'days' },
{ $label: '状态', $name: 'status' },
],
}),
},
});审批流程配套组件(jiess-client-sdk)
| 组件 | 路径 | 说明 |
|---|---|---|
ApproveItem | sdk/components/ApproveItem | 审批项展示 |
ApproveRecord | sdk/webSdk/pages/page-approve/components/ApproveRecord | 审批记录 |
ApproveProgress | sdk/webSdk/pages/page-approve/components/ApproveSteps | 审批步骤条 |
BaseApprove | sdk/webSdk/pages/page-approve/components/BaseApprove | 审批整体组件 |
DialogSubmit | sdk/webSdk/pages/page-approve/components/DialogSubmit | 审批提交弹框 |
DialogReject | sdk/webSdk/pages/page-approve/components/DialogReject | 审批驳回弹框 |
JFlowChart | @jiess/flow | 流程图可视化 |
校验规则合并机制
@jiess/plus 的校验规则分为内置规则和注入规则,在 RuleManger.getRuleData() 中合并:
typescript
// 源码合并顺序
getRuleData() {
const builtinRules = this.getBuiltinRules(); // 内置 14 条
const injectRules = this.config._ruleConfig?.ruleData || {}; // 注入规则
return { ...builtinRules, ...injectRules }; // 内置优先,注入覆盖同名
}合并优先级
javascript
const hook = $initHook({
globalConfig: {
_ruleConfig: {
ruleData: {
email: (value, label) => {
// ⚠️ 覆盖了内置 email 规则!
return /@company.com$/.test(value) ? undefined : `${label} 必须为公司邮箱`;
},
password: (value, label) => {
// ✅ 新增业务规则,不与内置冲突
return value?.length >= 8 ? undefined : `${label} 不能少于8位`;
},
},
},
},
});建议:除非确有必要,不要覆盖同名的内置规则。使用不同名称注入业务规则。
条件导出与自动检测
精确导入(推荐)
javascript
// 精确导入指定框架版本(体积最小)
import { $JiessTable, $JiessDialog } from '@jiess/plus/vue3'; // 仅 ElementPlus
import { $JiessList, $JiessDialog } from '@jiess/plus/vant'; // 仅 Vant
import { $JiessTable, $JiessDialog } from '@jiess/plus/react'; // 仅 AntDesign自动检测
javascript
// 自动检测框架 + 按需加载(体积较大,适合跨框架组件库)
import { $JiessTable, $JiessDialog } from '@jiess/plus/auto';Resolver 路径(高级)
javascript
// 用于 Vite/Webpack 的 resolver 插件开发
import { resolver } from '@jiess/plus/auto/resolver';
import { resolver } from '@jiess/plus/react/resolver';生产环境日志控制
在 $initHook 中,可注入 ActionManger 控制生产环境行为:
javascript
const hook = $initHook({
$name: 'my-app',
ui: element,
...Vue,
// 生产环境设置(内部会隐藏调试日志)
$env: import.meta.env.MODE,
});生产模式下,ActionManger 中的调试 console.log 会被跳过。
Hook 扩展体系
@jiess/plus 的 Hook<T> 基类提供 10 个可重写的钩子方法,用于在 BuildArea / BuildTable / BuildList 的各个生命周期节点插入自定义逻辑。
钩子方法清单
| 钩子 | 触发时机 | 典型用途 |
|---|---|---|
hookInitValues(nameManger) | NameManger 初始化时 | 设置字段默认值 |
hookNameManger(area) | NameManger 创建后 | 注册自定义字段处理器 |
hookNameMangerInput(values, field, val) | 字段值写入时 | 拦截/转换字段值 |
hookBuildRule(msg, callback) | 校验规则构建时 | 动态注入校验规则 |
hookFormParam(area, formParam) | 表单参数组装时 | 修改提交数据结构 |
hookItemCall(itemBuilder) | 每个表单项构建时 | 统一修改 item 配置 |
hookFormItem(name, result) | 表单项渲染结果生成后 | 后处理单个表单项 |
hookInitParam(area, binding, param) | 参数初始化时 | 修改 binding 绑定 |
hookProxyValue(area, options) | 响应式代理创建时 | 自定义代理行为 |
hookDialog(close, ctx, param) | 弹框关闭时 | 弹框关闭前数据清理 |
自定义 Hook 子类示例
javascript
import Hook from '@jiess/plus/_hook/Hook';
class MyHook extends Hook {
// 在表单项构建时统一添加 clearable
hookItemCall(itemBuilder) {
if (itemBuilder.config.$name) {
itemBuilder.config.clearable = true;
}
}
// 在校验规则构建时动态注入
hookBuildRule(msg, callback) {
// 根据业务条件动态添加规则
if (this.context.requireStrong) {
callback([{ validator: strongPasswordValidator }]);
}
}
// 在表单参数组装时过滤敏感字段
hookFormParam(area, formParam) {
delete formParam.password_confirm;
return formParam;
}
}
// 使用自定义 Hook
const hook = $initHook({
globalConfig: { _hook: MyHook },
ui: element,
...Vue,
});说明:Hook 子类通过
globalConfig._hook传入,所有BuildArea/BuildTable/BuildList实例都会使用该 Hook 类。不同构建器可通过泛型Hook<T>获取类型安全的上下文。