Skip to content

高级特性 ​

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/Classstart() 时创建一次不覆盖(首次创建后缓存)
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) ​

组件路径说明
ApproveItemsdk/components/ApproveItem审批项展示
ApproveRecordsdk/webSdk/pages/page-approve/components/ApproveRecord审批记录
ApproveProgresssdk/webSdk/pages/page-approve/components/ApproveSteps审批步骤条
BaseApprovesdk/webSdk/pages/page-approve/components/BaseApprove审批整体组件
DialogSubmitsdk/webSdk/pages/page-approve/components/DialogSubmit审批提交弹框
DialogRejectsdk/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> 获取类型安全的上下文。


下一步 ​