自定义视图部分区域渲染设计器的配置

自定义视图与界面设计器配置对接

在日常开发中,我们经常会遇到自定义视图的需求。自定义视图不仅需要与平台机制结合,还要实现与界面设计器中配置的字段和动作的无缝对接。本文将介绍如何将自定义视图与界面设计器中配置的字段和动作的无缝对接,实现字段和动作的渲染。

用大白话来讲就是:当前页面一部分是自定义的,一部分是设计器生成的

代码地址

目录

  1. 自定义表单视图与字段、动作的结合
  2. 自定义表格视图与字段、动作的结合

自定义表单视图与字段、动作的结合

首先需要在界面设计器配置好对应界面,虽然配置的页面样式跟期望展示的 UI 的不一样,但是数据的分发、汇总以及动作的交互也是一致的,所以我们可以通过自定义的方式替换这个页面的 UI,但是数据以及动作,是完全可以通过平台的能力获取的。

注册表单对应的 SPI

// CustomFormWidget.ts

import CustomForm from './CustomForm.vue';

@SPI.ClassFactory(
  BaseElementWidget.Token({
    viewType: ViewType.Form,
    widget: 'CustomFormWidget'
  })
)
export class CustomFormWidget extends FormWidget {
  public initialize(props: BaseElementObjectViewWidgetProps): this {
    super.initialize(props);
    this.setComponent(CustomForm);
    return this;
  }
}
<!-- CustomForm.vue -->

<template>
  <div class="custom-form-container">
    <div class="custom-form-tip">自定义视图</div>
  </div>
</template>
<script lang="ts">
  import { DslRender, DslRenderDefinition, PropRecordHelper } from '@kunlun/dependencies';
  import { createVNode, defineComponent, onMounted, PropType, ref, VNode } from 'vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
      formData: {
        type: Object as PropType<Record<string, any>>,
        default: () => ({})
      }
    }
  });
</script>

在上述的代码中,我们继承的是 FormWidget,那么这个页面会自动发起对应的请求,所有的数据都在 formData 中。

表单视图渲染动作

在最开始我们讲到过,当前页面是在界面设计器配置过,所有在CustomFormWidget里面是可以拿到当前页面配置的元数据信息,所以我们可以拿到界面设计器配置的字段跟动作

/// CustomFormWidget.ts

@Widget.Method()
protected renderActionVNodes() {
  // 从dsl中获取actionBar,actionBar里面包含了界面设计器配置的动作
  const actionBar = this.metadataRuntimeContext.viewDsl?.widgets.find((w) => w.slot === 'actionBar');

  if (actionBar) {
    // actionBar.widgets 就是界面设计器配置的动作,借助平台提供的DslRender.render方法,将对应的dsl转换成VNode
    return actionBar.widgets.map((w, index) =>
      DslRender.render({
        ...w,
        __index: index
      })
    );
  }

  return null;
}

因为 renderActionVNodes 方法返回的是 VNode,所以我们必须借助 vue 的 render 函数才能渲染。

<!-- ActionRender.vue -->

<script lang="ts">
  import { defineComponent } from 'vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
      renderActionVNodes: {
        type: Function,
        required: true
      }
    },
    render() {
      return this.renderActionVNodes();
    }
  });
</script>

ActionRender.vue中,通过 props 接收renderActionVNodes 方法,最终在 render 函数中执行,所以只需要在CustomForm.vue导入ActionRender.vue

<template>
  <div class="custom-form-container">
    <div class="custom-form-tip">自定义视图</div>

    <p style="color: red">下面是通过平台机制生成的动作</p>

    <div style="display: flex; gap: 10px">
      <action-render :renderActionVNodes="renderActionVNodes"></action-render>
    </div>
  </div>
</template>
<script lang="ts">
  import { DslRender, DslRenderDefinition, PropRecordHelper } from '@kunlun/dependencies';
  import { createVNode, defineComponent, onMounted, PropType, ref, VNode } from 'vue';
  import ActionRender from './components/ActionRender.vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
      renderActionVNodes: {
        type: Function,
        required: true
      }
    },
    components: {
      ActionRender
    }
  });
</script>
<style lang="scss">
  .custom-form-container {
    .custom-form-tip {
      color: var(--oio-primary-color);
      margin-bottom: var(--oio-margin);
      font-size: 24px;
    }
  }
</style>

表单视图渲染字段

渲染界面设计器配置的字段和刚刚讲到的动作是一致的。

// CustomFormWidget.ts
@Widget.Method()
  protected renderFieldVNodes() {
    // 获取界面设计器配置的字段
    const modelFields = this.metadataRuntimeContext.model.modelFields;

    if (modelFields.length) {
      //借助平台提供的DslRender.render方法,将对应的dsl转换成VNode
      return modelFields.map((w) => DslRender.render(w.template!));
    }

    return null;
  }

因为renderFieldVNodes 返回的也是 VNode,所以我们还是需要借助 vue 的 render 函数来渲染.

<!-- FieldRender.vue -->
<script lang="ts">
  import { defineComponent } from 'vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
      renderFieldVNodes: {
        type: Function,
        required: true
      }
    },
    render() {
      return this.renderFieldVNodes();
    }
  });
</script>

最终也是在CustomForm.vue中导入FieldRender.vue

下面是完整的代码:

// CustomFormWidget.ts

import {
  BaseElementObjectViewWidgetProps,
  BaseElementWidget,
  DslRender,
  FORM_WIDGET,
  FormWidget,
  SPI,
  ViewType,
  Widget
} from '@kunlun/dependencies';

import CustomForm from './CustomForm.vue';

@SPI.ClassFactory(
  BaseElementWidget.Token({
    viewType: ViewType.Form,
    widget: 'CustomFormWidget'
  })
)
export class CustomFormWidget extends FormWidget {
  public initialize(props: BaseElementObjectViewWidgetProps): this {
    super.initialize(props);
    this.setComponent(CustomForm);
    return this;
  }

  /**
   * 渲染字段VNode
   */
  @Widget.Method()
  protected renderFieldVNodes() {
    const modelFields = this.metadataRuntimeContext.model.modelFields;

    if (modelFields.length) {
      return modelFields.map((w) => DslRender.render(w.template!));
    }

    return null;
  }

  /**
   * 渲染动作VNode
   */
  @Widget.Method()
  protected renderActionVNodes() {
    const actionBar = this.metadataRuntimeContext.viewDsl?.widgets.find((w) => w.slot === 'actionBar');

    if (actionBar) {
      return actionBar.widgets.map((w, index) =>
        DslRender.render({
          ...w,
          __index: index
        })
      );
    }

    return null;
  }

  @Widget.Reactive()
  protected showFieldVNode = false;

  protected async mountedProcess() {
    await super.mountedProcess();

    this.showFieldVNode = true;
  }
}
<!-- CustomForm.vue -->
<template>
  <div class="custom-form-container">
    <div class="custom-form-tip">自定义视图</div>

    <p style="color: red">下面是通过平台机制生成的字段</p>

    <field-render v-if="showFieldVNode" :renderFieldVNodes="renderFieldVNodes"></field-render>

    <p style="color: red">下面是通过平台机制生成的动作</p>

    <div style="display: flex; gap: 10px"><action-render :renderActionVNodes="renderActionVNodes"></action-render></div>
  </div>
</template>
<script lang="ts">
  import { DslRender, DslRenderDefinition, PropRecordHelper } from '@kunlun/dependencies';
  import { createVNode, defineComponent, onMounted, PropType, ref, VNode } from 'vue';
  import FieldRender from './components/FieldRender.vue';
  import ActionRender from './components/ActionRender.vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
      renderActionVNodes: {
        type: Function,
        required: true
      },
      renderFieldVNodes: {
        type: Function,
        required: true
      },
    showFieldVNode: {
      type: Boolean,
      default: false
    }
    },
    components: {
      FieldRender,
      ActionRender
    }
  });
</script>
<style lang="scss">
  .custom-form-container {
    .custom-form-tip {
      color: var(--oio-primary-color);
      margin-bottom: var(--oio-margin);
      font-size: 24px;
    }
  }
</style>

注册 layout

registerLayout(
  `<view type="FORM">
    <element widget="CustomFormWidget" slot="form">
        <xslot name="fields" slotSupport="pack,field" />
    </element>
  </view>`,
  {
    moduleName: 'moduleName',
    model: 'model',
    viewType: ViewType.Form,
    actionName: 'actionName'
  }
);

自定义表格视图与字段动作的结合

注册表格对应的 SPI

// CustomTableWidget.ts

import {
  BaseElementObjectViewWidgetProps,
  BaseElementWidget,
  DslRender,
  SPI,
  TableWidget,
  ViewType,
  Widget
} from '@kunlun/dependencies';
import CustomTable from './CustomTable.vue';

@SPI.ClassFactory(
  BaseElementWidget.Token({
    viewType: ViewType.Table,
    widget: 'CustomTableWidget'
  })
)
export class CustomTableWidget extends TableWidget {
  public initialize(props: BaseElementObjectViewWidgetProps): this {
    super.initialize(props);
    this.setComponent(CustomTable);
    return this;
  }

  /**
   * 渲染行内动作VNode
   */
  @Widget.Method()
  protected renderRowActionVNodes() {
   // const table = this.metadataRuntimeContext.viewDsl?.widgets.find((w) => w.slot === 'table');

    // const rowAction = table?.widgets.find((w) => w.slot === 'rowActions');
    // this.refreshCallChaining;
    // if (rowAction) {
    //   return rowAction.widgets.map((w) => DslRender.render(w));
    // }

    // return null;

    const modelActions = this.metadataRuntimeContext.model.modelActions;

    if (modelActions.length) {
      return modelActions.map((w) => DslRender.render(w.template!));
    }

    return null;
  }

  /**
   * 渲染动作VNode
   */
  @Widget.Method()
  protected renderActionVNodes() {
    const actionBar = this.metadataRuntimeContext.viewDsl?.widgets.find((w) => w.slot === 'actions');

    if (actionBar) {
      return actionBar.widgets.map((w, index) =>
        DslRender.render({
          ...w,
          __index: index
        })
      );
    }

    return null;
  }
}

在上述代码中,我们继承的是TableWidget,所以页面也会自动发起查询,并且定义了renderRowActionVNodesrenderActionVNodes方法,用于渲染行内动作和动作。

表格视图渲染动作

<!-- CustomTable.vue -->
<template>
  <div class="custom-table-container">
    <div class="custom-table-tip">自定义视图</div>

    <div style="display: flex; gap: 10px">
      <p style="color: red; margin-top: 10px">这是表格的动作</p>
      <action-render :renderActionVNodes="renderActionVNodes"></action-render>
    </div>

    <p style="color: red; margin-top: 10px">这是表格的数据跟行内动作</p>
    <div>
      <div v-for="(row, index) in dataSource" :key="row.index">
        <div style="display: flex">
          <div><span>行数据</span> <span> ID:{{ row.id }}</span></div>
          <div>
            <span>行动作</span>
            <span>
              <row-action-render
                :renderRowActionVNodes="renderRowActionVNodes"
                :row="row"
                :rowIndex="index"
                :parentHandle="currentHandle"
              ></row-action-render>
            </span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType } from 'vue';
  import ActionRender from './components/ActionRender.vue';
  import RowActionRender from './components/RowActionRender.vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
        currentHandle: {
          type: String,
          required: true
        },
      renderActionVNodes: {
        type: Function,
        required: true
      },
      renderRowActionVNodes: {
        type: Function,
        required: true
      },
      dataSource: {
        type: Array as PropType<any[]>,
        default: () => []
      }
    },
    components: {
      RowActionRender,
      ActionRender
    }
  });
</script>
<style lang="scss">
  .custom-table-container {
    .custom-table-tip {
      color: var(--oio-primary-color);
      margin-bottom: var(--oio-margin);
      font-size: 24px;
    }
  }
</style>

ActionRender.vue跟表单中的ActionRender.vue一样,内部也是在 render 函数中调用renderActionVNodes

RowActionRender.vue有点特殊,下面是对应的代码(固定写法)。

<script lang="ts">
  import { ActionBar, RowActionBarWidget, uniqueKeyGenerator } from '@kunlun/dependencies';
  import { debounce } from 'lodash-es';
  import { createVNode, defineComponent } from 'vue';

  export default defineComponent({
    inheritAttrs: false,
    props: {
      row: {
        type: Object,
        required: true
      },
      rowIndex: {
        type: Number,
        required: true
      },
      renderRowActionVNodes: {
        type: Function,
        required: true
      },
      parentHandle: {
          type: String,
          required: true
        }
    },
    render() {
      const vnode = this.renderRowActionVNodes();

      return createVNode(
        ActionBar,
        {
          widget: 'rowAction',
          parentHandle: this.parentHandle,
          inline: true,
          activeRecords: this.row,
          rowIndex: this.rowIndex,
          key: this.rowIndex,
          refreshWidgetRecord: debounce((widget?: RowActionBarWidget) => {
            if (widget) {
              widget.setCurrentActiveRecords(this.row);
            }
          })
        },
        {
          default: () => vnode
        }
      );
    }
  });
</script>

注册 layout

import { registerLayout, ViewType } from '@kunlun/dependencies';

registerLayout(
  `<view type="TABLE">
    <element widget="CustomTableWidget" slot="table" slotSupport="field">
            <element widget="expandColumn" slot="expandRow" />
            <xslot name="fields" slotSupport="field" />
            <element widget="rowActions" slot="rowActions" slotSupport="action" />
        </element>
</view>`,
  {
    moduleName: 'resource',
    model: 'resource.ResourceProvince',
    viewType: ViewType.Table
  }
);

本文讲解了自定义视图与界面设计器中配置的字段和动作的无缝对接,以实现自定义视图的功能,本质上是将界面设计器配置的字段、动作,渲染成对应的 VNode,然后在自定义的页面渲染。

Oinone社区 作者:汤乾华原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/17225.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (1)
汤乾华's avatar汤乾华数式员工
Previous 2024年9月12日 am11:23
Next 2024年9月12日 pm10:16

相关推荐

  • oio-spin 加载中

    用于页面和区块的加载中状态。 何时使用 页面局部处于等待异步数据或正在渲染过程时,合适的加载动效会有效缓解用户的焦虑。 API 参数 说明 类型 默认值 版本 delay 延迟显示加载效果的时间(防止闪烁) number (毫秒) – loading 是否为加载中状态 boolean true wrapperClassName 包装器的类属性 string –

    2023年12月18日
    1.4K00
  • 前端自定义左树右表中的树

    在 oinone 平台中,提供了默认的左树右表的视图,用户可以通过界面设计器配置,默认的树视图不一定满足所有需求,尤其当需要自定义功能或复杂的交互时,我们可以通过自定义视图来实现更灵活的展现。 本文将带你一步步了解如何自定义左树右表视图中的树组件。 自定义树视图 1. 使用界面设计器配置视图 首先,我们需要通过界面设计器生成基础的左树右表视图。界面设计器允许用户根据不同需求进行拖拽配置,快速创建可视化界面。 配置完视图之后,我们可以重写左侧的树组件。Oinone 的默认树组件是 TableSearchTreeWidget,通过自定义的方式,我们可以实现更高级的功能。 2. 重写 TableSearchTreeWidget import { BaseElementWidget, SPI, TableSearchTreeWidget, ViewType } from '@kunlun/dependencies'; import CustomTableSearchTree from './CustomTableSearchTree.vue'; @SPI.ClassFactory( BaseElementWidget.Token({ viewType: [ViewType.Table, ViewType.Form], widget: 'tree', model: 'resource.k2.Model0000000100' // 改成自己的模型 }) ) export class CustomTableSearchTreeWidget extends TableSearchTreeWidget { public initialize(props) { super.initialize(props); this.setComponent(CustomTableSearchTree); return this; } } 3. 定义 Vue 树组件 接下来,我们来实现 CustomTableSearchTree.vue 组件。这个组件将处理树的数据加载、节点选中等逻辑。你可以根据项目的需要修改其中的交互逻辑或 UI 设计。 <template> <a-tree :load-data="onLoadData" :tree-data="treeData" @select="onSelected" /> </template> <script lang="ts"> import { OioTreeNode, TreeUtils } from '@kunlun/dependencies'; import { computed, defineComponent } from 'vue'; export default defineComponent({ props: { rootNode: { type: Object }, loadData: { type: Function, required: true }, onSelected: { type: Function, required: true } }, setup(props) { // // 计算树的数据源,使用 TreeUtils 处理 const treeData = computed(() => { return TreeUtils.fillLoadMoreAction([…(props.rootNode?.children || [])]); }); // 异步加载子节点 const onLoadData = async (node) => { return await props.loadData(node.dataRef); }; // 处理节点选中事件 const onSelected = ( selectedKeys: string[], e: { nativeEvent: PointerEvent; node: { dataRef: OioTreeNode }; selected: boolean } ) => { props.onSelected?.(e.node.dataRef, e.selected); }; return { treeData, onLoadData, onSelected }; } }); </script> 4. 自定义…

    2024年10月21日
    3.0K00
  • 【前端】低无一体部署常见问题

    如何检查上传的SDK是否有效? 1. 在任意页面刷新后,查看是否发起【查询SDK组件】的请求。 2. 在返回的js和css列表中是否能找到在界面设计器上传的js和css文件。 3. 检查浏览器的Console中是否有组件相关报错。 4. 检查sdk中是否包含了启动工程未加入的包依赖。 启动工程包依赖:main.ts VueOioProvider( { dependencies: { vue: import('vue'), lodashEs: import('lodash-es'), antDesignVue: import('ant-design-vue'), elementPlusIconsVue: import('@element-plus/icons-vue'), elementPlus: import('element-plus'), kunlunDependencies: import('@kunlun/dependencies'), kunlunVueUiAntd: import('@kunlun/vue-ui-antd'), kunlunVueUiEl: import('@kunlun/vue-ui-el') } } ); SDK依赖:rollup.config.ts const globals = { vue: 'vue', 'lodash-es': 'lodashEs', 'ant-design-vue': 'antDesignVue', '@element-plus/icons-vue': 'elementPlusIconsVue', 'element-plus': 'elementPlus', '@kunlun/dependencies': 'kunlunDependencies', '@kunlun/vue-ui-antd': 'kunlunVueUiAntd', '@kunlun/vue-ui-el': 'kunlunVueUiEl', '@kunlun/mobile-dependencies': 'kunlunMobileDependencies', '@kunlun/vue-ui-mobile-vant': 'kunlunVueUiMobileVant' }; 上述两个文件配置的依赖和对应名称必须匹配才能在sdk上传后正常运行,否则会出现内存变量无法共享的问题。 当未发起【查询SDK组件】的请求时如何处理? 1. 在任意页面刷新后,查看manifest.js加载路径。 业务工程通常为:http://${host}:${port}/manifest.js 设计器镜像中通常为:http://${host}:${port}/config/manifest.js 2. 若未正确加载manifest.js,则在dist目录中根据请求路径添加manifest.js文件。此文件称为运行时配置文件,可点击查看参考文档。 runtimeConfigResolve({ plugins: { usingRemote: true } });

    低无一体 2023年11月1日
    2.5K00
  • Oinone移动端快速入门

    介绍 oinone的pc端的页面默认都可以在移动端直接访问。自定义mask、layout、视图组件、字段组件、动作组件方式都参考pc端实现。目前移动端的UI组件是基于vant@3.6.0版本开发,如有自定义部分的代码,推荐使用该组件库。 “注意”: 由于移动端和pc端在交互上的巨大差异,两端用的是不同的UI组件库是,按照此约定开发的自定义组件在两端也是无法相互兼容的,在pc端自定义的组件或者页面,不会在移动端自动适配,需要自行开发对应的移动端组件或者页面。 工程搭建 移动端很多交互跟pc端差异很大,所以移动端的我们采用的方案是独立用一套移动端的UI框架实现,而不是简单的做页面布局自适应,所以移动端需要跟pc端一样独立部署一套前端工程。 参考文档:【前端】移动端工程结构最佳实践(v4/v5) 如何区分多端 在界面设计器设计页面的时候,可以通过顶部的多端设备的图标切换在各端的页面效果。 pc端页面 切换为移动端后的页面 注意:大部分情况下,pc端和移动端可以共享一个设计的页面,然后通过上面的方法区分两端,如果移动端的页面交互差异很大,那更推荐独立新建一个页面专门给移动端使用。 模块 模块在定义的时候可以通过注解@Module.clientTypes决定当前模块在哪些端展示 package pro.shushi.pamirs.demo.api; import org.springframework.stereotype.Component; import pro.shushi.pamirs.business.api.BusinessModule; import pro.shushi.pamirs.core.common.CommonModule; import pro.shushi.pamirs.file.api.FileModule; import pro.shushi.pamirs.meta.annotation.Module; import pro.shushi.pamirs.meta.base.PamirsModule; import pro.shushi.pamirs.meta.common.constants.ModuleConstants; import pro.shushi.pamirs.meta.enmu.ClientTypeEnum; import pro.shushi.pamirs.user.api.UserModule; @Component @Module( name = DemoModule.MODULE_NAME, displayName = "oinoneDemo工程", version = "1.0.0", // 客户端类型,默认是PC和MOBILE端都展示 clientTypes = {ClientTypeEnum.PC, ClientTypeEnum.MOBILE}, // 登录后默认访问 priority 值最小的模块 priority = 1, dependencies = {ModuleConstants.MODULE_BASE, CommonModule.MODULE_MODULE, UserModule.MODULE_MODULE, BusinessModule.MODULE_MODULE, FileModule.MODULE_MODULE } ) @Module.module(DemoModule.MODULE_MODULE) @Module.Advanced(selfBuilt = true, application = true) public class DemoModule implements PamirsModule { public static final String MODULE_MODULE = "demo_core"; public static final String MODULE_NAME = "DemoCore"; @Override public String[] packagePrefix() { return new String[]{ "pro.shushi.pamirs.demo" }; } } 菜单 界面设计器设置方式 在菜单设置的时候可以选择“显示设备” 低代码设置方式 通过注解@UxMenu.clientTypes设置显示设备 package pro.shushi.pamirs.demo.core.init.menu; import pro.shushi.pamirs.boot.base.constants.ViewActionConstants; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxRoute; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxMenu; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxMenus; import pro.shushi.pamirs.demo.api.model.DemoItem; import pro.shushi.pamirs.demo.api.model.DemoItemCategory; import pro.shushi.pamirs.meta.enmu.ClientTypeEnum; @UxMenus() public class DemoMenus implements ViewActionConstants { // 同时在pc端和移动端显示 @UxMenu(value = "商品中心", clientTypes = {ClientTypeEnum.PC, ClientTypeEnum.MOBILE}) class ItemPMenu{ @UxMenu("商品类目") class DemoItemAndCateMenu { // 只在pc端显示 @UxMenu(value = "商品管理", clientTypes = {ClientTypeEnum.PC}) @UxRoute(DemoItem.MODEL_MODEL) class DemoItemMenu { } // 只在移动端显示 @UxMenu(value = "类目管理", clientTypes = {ClientTypeEnum.MOBILE}) @UxRoute(DemoItemCategory.MODEL_MODEL) class DemoItemCategoryMenu { } } } } 组件 界面设计器选中组件后,可以在右边属性面板看到“显示设备”的配置,默认为空,为空则表示在pc端和移动端都显示

    2024年9月19日
    2.2K00
  • 前端6.2.x升级指南

    升级背景 从 6.2.x 版本开始,平台底层核心代码已全面开源(设计器相关代码除外),本次升级涉及包名变更和配置调整,以下是详细的升级步骤 1. 更新 .npmrc 配置 修改当前项目根目录 .npmrc 文件,内容如下: registry=https://registry.npmmirror.com/ @oinone:registry=http://nexus.shushi.pro/repository/kunlun/ @kunlun:registry=http://nexus.shushi.pro/repository/kunlun/ shamefully-hoist=true legacy-peer-deps=true link-workspace-packages = true prefer-workspace-packages = true recursive-install = true lockfile=true 2. 包名变更 以前的包是 @kunlun/xxxx,现在的包名是@oinone/kunlun开头,所以需要全部替换修改。 旧包名 新包名 @kunlun/dependencies @oinone/kunlun-dependencies @kunlun/vue-ui-antd @oinone/kunlun-vue-ui-antd 3. 升级依赖版本 修改所有 package.json 中更新所有平台相关依赖: – "@kunlun/dependencies": "~5.7.0" + "@oinone/kunlun-dependencies": "~6.2.0" boot工程的package.json新增devDependencies依赖 "devDependencies": { "@types/lodash": "4.14.182", "@types/lodash-es": "4.17.6", ….. } 4. 更新代码引用 全局搜索并替换代码中的所有 @kunlun/ 为 @oinone/kunlun- 完整的 main.ts import 'ant-design-vue/dist/antd.min.css'; import 'element-plus/dist/index.css'; import '@oinone/kunlun-vue-ui-antd/dist/oinone-kunlun-vue-ui-antd.css'; import '@oinone/kunlun-vue-ui-el/dist/oinone-kunlun-vue-ui-el.css'; import '@oinone/kunlun-designer-common/dist/oinone-kunlun-designer-common.css'; import '@oinone/kunlun-model-designer/dist/oinone-kunlun-model-designer.css'; import '@oinone/kunlun-workflow-designer/dist/oinone-kunlun-workflow-designer.css'; import '@oinone/kunlun-workflow/dist/oinone-kunlun-workflow.css'; import '@oinone/kunlun-data-designer/dist/oinone-kunlun-data-designer.css'; import '@oinone/kunlun-microflow-designer/dist/oinone-kunlun-microflow-designer.css'; import 'reflect-metadata'; import ElementPlus from 'element-plus'; import { App } from 'vue'; import { VueOioProvider, RuntimeContextManager } from '@oinone/kunlun-dependencies'; // 设计器 import '@oinone/kunlun-ui-designer-dependencies'; import '@oinone/kunlun-print-designer-dependencies'; import '@oinone/kunlun-workflow'; import '@oinone/kunlun-workflow-designer'; import '@oinone/kunlun-model-designer'; import '@oinone/kunlun-data-designer'; import '@oinone/kunlun-data-designer-open-pc'; import '@oinone/kunlun-eip-dependencies'; import '@oinone/kunlun-ai-dependencies'; import '@oinone/kunlun-microflow-designer'; import '@oinone/kunlun-designer-common-ee'; // 下面三个依赖是当前工程的包,请根据实际场景修改 import '@ss/oinone'; import '@ss/admin-widget'; import '@ss/project'; VueOioProvider( { browser: { title: 'Oinone – 构你想象!', favicon: 'https://pamirs.oss-cn-hangzhou.aliyuncs.com/pamirs/image/default_favicon.ico' } }, [ () => { /// 获取当前vue实例 const app = RuntimeContextManager.createOrReplace().frameworkInstance as App; } ] ); 当配置全部修改完成后,重写安装依赖 # 清理旧依赖 pnpm clean # 安装新依赖 pnpm install

    2025年6月17日
    66200

Leave a Reply

Please Login to Comment