3.5.7.2 自定义母版

母版是什么

在业务系统中,母版是一种全局通用的组件,用于包裹每个页面的元素。这个概念类似于 PPT 中的母版,它定义了页面的整体结构、样式和布局,使得系统具有一致的外观和风格。

特点:

  1. 全局通用:母版是全局性的,适用于系统中的每个页面,确保一致性的用户体验。

  2. 包裹元素:母版包裹每个页面的元素,定义了整体的结构和布局。

  3. 外观一致性:通过统一的母版设计,系统达到外观和风格的一致性。

与 PPT 母版的类比:

在母版的概念上,与 PPT 中的母版类似,都是用于定义整体结构和样式,确保每个页面都具有一致的外观。

默认母版范围:

image.png

图3-5-7-20 默认母版范围

作用场景

在系统中,我们提供了多个纬度的母版,包括全局、应用和页面纬度。这样的设计允许根据不同的业务场景选择合适的母版纬度,以满足不同层次的定制需求。

母版纬度:

  1. 全局母版:

    • 覆盖系统中所有页面,确保全局的一致性和统一的用户体验。
    • 定义全局性的结构、样式和布局。
  2. 应用母版:

    • 适用于特定应用或模块,定制化程度介于全局和页面之间。
    • 允许在不同应用间实现一定的差异化。
  3. 页面母版:

    • 面向具体页面,提供最大的定制化空间。
    • 允许在不同页面中定义不同的结构和样式。

选择纬度:

  • 业务场景决定:根据具体的业务场景和需求选择合适的母版纬度。
  • 定制化需求:如果需要全局一致性,选择全局母版;如果在应用层面有特定需求,选择应用母版;如果需要最大的灵活性和定制化,选择页面母版。

参数说明:

在系统中,使用 registerMask 注册母版时,需要提供两个参数。第一个参数是母版的 XML,第二个参数用于控制母版的注册行为,包括 module、moduleName、model 和 actionName。

  1. 母版 XML(第一个参数):

    • 提供母版的 XML 描述,定义了母版的结构和样式。
  2. 控制参数(第二个参数):

    • module:指定模块的名称。
    • moduleName:指定模块的显示名称。
    • model:指定母版所属的模型。
    • actionName:指定母版的操作名称,可以是字符串或字符串数组。

全局母版

可以使用 registerMask 注册母版。当第二个参数为 {} 时,即代表注册全局母版。

示例工程目录

以下是需关注的工程目录示例,并确保导入导出依赖正确:

image.png

图3-5-7-21 全局纬度注册母版工程目录示例

示例代码

以下是一个示例代码:

import { registerMask } from '@kunlun/dependencies';

/**
 * mask: 在做系统时,我们通常会把外层的布局(菜单、顶部导航)等抽出公共组件,公共组件会抽离全局通用。类似ppt母版的概念即为Mask
 * registerMask 第二个入参为{}即注册了全局得母版
 *
 * 和默认母版相比移除右上角消息、语言切换、用户
 * `<block>
 *     <widget widget="notification" />
 *     <widget widget="divider" />
 *     <widget widget="language" />
 *     <widget widget="divider" />
 *     <widget widget="user" />
 * </block>`
 */
const registerGlobalMask = () => {
    registerMask(`
    <mask>
        <multi-tabs />
        <header>
            <widget widget="app-switcher" />
        </header>
        <container>
            <sidebar>
                <widget widget="nav-menu" height="100%" />
            </sidebar>
            <content>
                <breadcrumb />
                <block width="100%">
                    <widget width="100%" widget="main-view" />
                </block>
            </content>
        </container>
    </mask>`, {});
}

registerGlobalMask();

图3-5-7-22 全局纬度注册母版代码示例

复制这段代码执行下registerGlobalMask()试试看吧

效果

右上角消息、语言切换、用户被移除。

image.png

图3-5-7-23 全局纬度注册母版效果示例

应用母版

在系统中,可以使用 registerMask 注册母版。当第二个参数为 {moduleName: 'resource'} 时,即注册了 resource(资源)应用的母版。

示例工程目录

以下是需关注的工程目录示例,更新导出./moduleMask:

image.png

图3-5-7-24 应用纬度注册母版工程目录示例

示例代码

以下是一个示例代码:

/**
 * registerMask 第二个入参为{moduleName: 'resource'}即注册了resource(资源)应用的母版
 *
 * resource来源: 通常是浏览器url上的module
 *
 * 和默认模版相比拿掉了菜单
 * `<sidebar>
 *    <widget widget="nav-menu" height="100%" />
 *  </sidebar>`
 * */
const registerModuleMask = () => {
    registerMask(`<mask>
    <multi-tabs />
    <header>
        <widget widget="app-switcher" />
        <block>
            <widget widget="notification" />
            <widget widget="divider" />
            <widget widget="language" />
            <widget widget="divider" />
            <widget widget="user" />
        </block>
    </header>
    <container>
        <content>
            <breadcrumb />
            <block width="100%">
                <widget width="100%" widget="main-view" />
            </block>
        </content>
    </container>
</mask>`, { moduleName: 'resource'})
}

registerModuleMask();

图3-5-7-25 应用纬度注册母版代码示例

在这个示例中,通过将第二个参数设置为 {moduleName: 'resource'},实现了注册 resource 应用的母版。该母版包含了特定于 resource 应用的全局结构和布局,并在示例中去掉了菜单部分。

这样的设计使得可以根据不同应用注册不同的母版,以满足应用层面的定制需求。

效果

image.png

图3-5-7-26 应用纬度注册母版效果示例

页面母版

在系统中,可以使用 registerMask 注册母版。当第二个参数为 {moduleName: 'resource', model: 'resource.ResourceRegionProxyModel'} 时,即注册了 resource(资源)应用和 这个应用下ResourceRegionProxyModel(地区)模型的母版。

示例工程目录

以下是需关注的工程目录示例,更新导出./viewMask:

image.png

图3-5-7-27 页面纬度注册母版工程目录示例

示例代码

以下是一个示例代码:

/**
 * registerMask 第二个入参为{moduleName: 'resource', model: 'resource.ResourceRegionProxyModel'}即注册了resource(资源)和resource.ResourceRegionProxyModel(地区)模型的母版
 *
 * resource来源: 通常是浏览器url上的module
 * model来源:  通常是浏览器url上的model
 *
 * 拿掉菜单
 * `<sidebar>
 *    <widget widget="nav-menu" height="100%" />
 *  </sidebar>`
 *
 *  拿掉appFounder
 *  `<widget widget="app-switcher" />`
 * */
const registerViewMask = () => {
  registerMask(`<mask>
    <multi-tabs />
    <header>
        <block>
            <widget widget="notification" />
            <widget widget="divider" />
            <widget widget="language" />
            <widget widget="divider" />
            <widget widget="user" />
        </block>
    </header>
    <container>
        <content>
            <breadcrumb />
            <block width="100%">
                <widget width="100%" widget="main-view" />
            </block>
        </content>
    </container>
</mask>`, { moduleName: 'resource', model: 'resource.ResourceRegionProxyModel'})
}
registerViewMask();

图3-5-7-28 页面纬度注册母版代码示例

在这个示例中,通过将第二个参数设置为 {moduleName: 'resource', model: 'resource.ResourceRegionProxyModel'},实现了注册 Resource 应用和 ResourceRegionProxyModel 模型的母版。该母版包含了特定于这两个条件的全局结构和布局,并在示例中去掉了菜单和应用切换部分。

效果

image.png

图3-5-7-29 页面纬度注册母版效果示例

这样的设计使得可以根据不同应用和模型注册不同的母版,以满足不同层次的定制需求

扩展母版

在系统中,除了平台内置的母版组件和布局外,开发者还可以自由地添加自定义的组件和布局,以决定应用的个性化。以下是一些示例代码和说明:

注册母版组件

在这个示例中,我们注册了一个名为 custom-mask-widget 的自定义组件,并使用 CustomMaskWidget 类初始化了该组件。

示例工程目录

以下是需关注的工程目录示例,更新导出./widget:

image.png

图3-5-7-30 扩展母版工程目录示例

示例代码

以下是代码示例和相应的组件实现:

1. 注册自定义组件:

import { SPI, MaskWidget } from '@kunlun/dependencies'
import CustomMaskWidgetVue from './MaskWidget.vue'

@SPI.ClassFactory(MaskWidget.Token({ widget: 'custom-mask-widget' }))
export class CustomMaskWidget extends MaskWidget {
  public initialize(props) {
    super.initialize(props);
    this.setComponent(CustomMaskWidgetVue);
    return this;
  }
}

图3-5-7-31 注册自定义组件(TS)示例

在这段代码中,我们使用 @SPI.ClassFactory 注解来创建 CustomMaskWidget 类,并使用 MaskWidget.Token 注入组件的标识。通过 setComponent 方法,我们将组件与 CustomMaskWidgetVue 相关联。

2. 自定义组件实现(MaskWidget.vue):

  <template>
    <div class="mask-widget-wrapper">
      <h1>Mask组件</h1>
    </div>
  </template>

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

    export default defineComponent({
      inheritAttrs: false,
      name: 'CustomMaskWidgetVue'
    })
  </script>

  <style lang="scss">
    .mask-widget-wrapper {
      display: flex;
      align-items: center;
      background-color: var(--oio-disable-color);
      h1 {
        color: red;
      }
    }
  </style>

图3-5-7-32 注册自定义组件(Vue)示例

在 MaskWidget.vue 文件中,我们定义了 CustomMaskWidgetVue 组件的模板、逻辑和样式。这个组件简单地展示了一个包含标题的容器。

通过这个示例,我们展示了如何使用 SPI 和 Vue 来注册和实现自定义组件,以满足系统中的个性化需求

自定义母版

在这个示例中,我们注册了一个全局母版,并将自定义组件 custom-mask-widget 与母版结合。

示例工程目录

以下是需关注的工程目录示例,新导出了./globalMask:

image.png

图3-5-7-33 自定义母版工程目录示例

示例代码

以下是代码示例:

const registerGlobalMask = () => {
  registerMask(`
    <mask>
        <multi-tabs />
        <header>
            <widget widget="language" />
+            <widget widget="custom-mask-widget" />
        </header>
        <container>
            <sidebar>
                <widget widget="nav-menu" height="100%" />
            </sidebar>
            <content>
                <breadcrumb />
                <block width="100%">
                    <widget width="100%" widget="main-view" />
                </block>
            </content>
        </container>
    </mask>`, {});
}

registerGlobalMask();

图3-5-7-34 自定义母版组件使用示例

在这段代码中,我们使用 registerMask 注册了一个全局母版,其中包含了多个内置组件和布局元素。通过 的方式,我们将自定义组件 custom-mask-widget 添加到了母版的头部(header)中

效果

image.png

图3-5-7-35 自定义母版效果示例

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9265.html

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

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am9:13
下一篇 2024年5月23日 am9:15

相关推荐

  • 节点动作

    节点动作为触发和结束结点中间的动作,点击节点名称可以进行修改。

    Oinone 7天入门到精通 2024年6月20日
    1.1K00
  • 3.5.7.9 自定义多Tab

    在业务中,可能会遇到需要对多tab的交互或UI做全新设计的需求,这个时候可以自定义多tab组件支持。 首先继承平台的MultiTabsWidget组件,将自己vue文件设置到component处 import { MultiTabsWidget, SPI, ViewWidget } from '@kunlun/dependencies'; import Component from './CustomMultiTabs.vue'; @SPI.ClassFactory( ViewWidget.Token({ // 这里的tagName跟平台的组件一样,这样才能覆盖平台的组件 tagName: ['multi-tabs', 'MultiTabs'] }) ) export class CustomMultiTabsWidget extends MultiTabsWidget{ public initialize(props) { super.initialize(props); // 设置自定义的vue组件 this.setComponent(Component); return this; } } vue文件中继承平台的props,编写自定义页面代码 export const MultiTabsProps = { /** * 组件是否可见 */ invisible: { type: Boolean }, /** * tab列表数据 */ tabs: { type: Array as PropType<MultiTab[]> }, /** * 当前激活的tab */ activeTab: { type: Object as PropType<MultiTab> }, /** * 鼠标悬浮所在的tab */ hoverTab: { type: Object as PropType<MultiTab> }, /** * 鼠标经过tab事件回调 */ onMouseenterTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 鼠标离开tab事件回调 */ onMouseleaveTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 点击tab */ onClickTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 刷新当前tab */ onRefreshCurrentTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭当前tab */ onCloseCurrentTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭除当前tab外的其他所有tab */ onCloseOtherTabs: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭当前tab左侧的所有tab */ onCloseLeftTabs: { type: Function as…

    2024年5月23日
    1.1K00
  • 登录日志

    1. 登录日志 登录日志:记录企业成员/用户登录平台的历史明细,包括登录时间、位置、IP、登录设备、登录平台等信息,登录平台包括:PC Web、小程序、H5、APP。登录日志不需要通过审计规则订阅,平台会记录每位用户的登录日志。 操作支持导出、查看详情。

    2024年6月20日
    1.1K00
  • 4.2.8 自定义组件与设计器结合(新)

    界面设计器组件管理页面添加组件 进入组件的元件管理页面 点击“添加元件” 设计元件的属性 这里以是否“显示清除按钮”作为自定义属性从左侧拖入到中间设计区域,然后发布 点击“返回组件” 鼠标悬浮到卡片的更多按钮的图标,弹出下拉弹出“低无一体”的按钮 在弹窗内点击“生成SDK”的按钮 生成完成后,点击“下载模板工程” 解压模板工程kunlun-sdk.zip 解压后先查看README.MD,了解一下工程运行要点,可以先运行 npm i 安装依赖 再看kunlun-plugin目录下已经有生成好的组件对应的ts和vue文件 下面在vue文件内增加自定义代码,可以运行 npm run dev 在开发模式下调试看效果 <template> <div class="my-form-string-input"> <oio-input :value="realValue" @update:value="change" > <template #prepend>MyPrepend</template> </oio-input> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; import { OioInput } from '@kunlun/vue-ui-antd'; export default defineComponent({ name: 'customField1', components: { OioInput }, props: { value: { type: String }, change: { type: Function }, }, setup(props) { const realValue = ref<string | null | undefined>(props.value); return { realValue }; } }); </script> <style lang="scss"> .my-form-string-input { border: 1px solid red; } </style> 确定改好代码后运行 npm run build,生成上传所需的js和css文件 可以看到 kunlun-plugin目录下多出了dist目录,我们需要的是 kunlun-plugin.umd.js 和 kunlun-plugin.css 这2个文件 再次回到组件的“低无一体”管理弹窗页面,上传上面生成的js和css文件,并点击“确定”保存,到这里我们的组件就新增完成了。 下面我们再到页面设计器的页面中使用上面设计的组件(这里的表单页面是提前准备好的,这里就不介绍如何新建表单页面了) 将左侧组件库拉直最底部,可以看到刚刚新建的组件,将其拖至中间设计区域,我们可以看到自定义组件的展示结果跟刚刚的代码是对应上的(ps: 如果样式未生效,请刷新页面查看,因为刚刚上传的js和css文件在页面初始加载的时候才会导入进来,刚刚上传的动作未导入新上传的代码文件),再次点击设计区域中的自定义组件,可以看到右侧属性设置面板也出现了元件设计时拖入的属性。 最后再去运行时的页面查看效果,与代码逻辑一致!

    2024年5月23日
    1.2K00
  • 4.1.24 框架之分库分表

    随着数据库技术的发展如分区设计、分布式数据库等,业务层的分库分表的技术终将成老一辈程序员的回忆,谈笑间扯扯蛋既羡慕又自吹地说到“现在的研发真简单,连分库分表都不需要考虑了”。竟然这样为什么要写这篇文章呢?因为现今的数据库虽能解决大部分场景的数据量问题,但涉及核心业务数据真到过亿数据后性能加速降低,能给的方案都还有一定的局限性,或者说性价比不高。相对性价比比较高的分库分表,也会是现阶段一种不错的补充。言归正传oinone的分库分表方案是基于Sharding-JDBC的整合方案,所以大家得先具备一点Sharding-JDBC的知识。 一、分表(举例) 做分库分表前,大家要有一个明确注意的点就是分表字段的选择,它是非常重要的,与业务场景非常相关。在明确了分库分表字段以后,甚至在功能上都要做一些妥协。比如分库分表字段在查询管理中做为查询条件是必须带上的,不然效率只会更低。 Step1 新建ShardingModel模型 ShardingModel模型是用于分表测试的模型,我们选定userId作为分表字段。分表字段不允许更新,所以这里更新策略设置类永不更新,并在设置了在页面修改的时候为readonly package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.boot.base.ux.annotation.field.UxWidget; import pro.shushi.pamirs.boot.base.ux.annotation.view.UxForm; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.enmu.FieldStrategyEnum; @Model.model(ShardingModel.MODEL_MODEL) @Model(displayName = "分表模型",summary="分表模型",labelFields ={"name"} ) public class ShardingModel extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.ShardingModel"; @Field(displayName = "名称") private String name; @Field(displayName = "用户id",summary = "分表字段",immutable=true/* 不可修改 **/) @UxForm.FieldWidget(@UxWidget(readonly = "scene == 'redirectUpdatePage'"/* 在编辑页面只读 **/ )) @Field.Advanced(updateStrategy = FieldStrategyEnum.NEVER) private Long userId; } 图4-1-24-1 新建ShardingModel模型 Step2 配置分表策略 配置ShardingModel模型走分库分表的数据源pamirsSharding 为pamirsSharding配置数据源以及sharding规则 a. pamirs.sharding.define用于oinone的数据库表创建用 b. pamirs.sharding.rule用于分表规则配置 pamirs: load: sessionMode: true framework: system: system-ds-key: base system-models: – base.WorkerNode data: default-ds-key: pamirs ds-map: base: base modelDsMap: "[demo.ShardingModel]": pamirsSharding #配置模型对应的库 图4-1-24-2 指定模型对应数据源 pamirs: sharding: define: data-sources: ds: pamirs pamirsSharding: pamirs #申明pamirsSharding库对应的pamirs数据源 models: "[trigger.PamirsSchedule]": tables: 0..13 "[demo.ShardingModel]": tables: 0..7 table-separator: _ rule: pamirsSharding: #配置pamirsSharding库的分库分表规则 actual-ds: – pamirs #申明pamirsSharding库对应的pamirs数据源 sharding-rules: # Configure sharding rule ,以下配置跟sharding-jdbc配置一致 – tables: demo_core_sharding_model: #demo_core_sharding_model表规则配置 actualDataNodes: pamirs.demo_core_sharding_model_${0..7} tableStrategy: standard: shardingColumn: user_id shardingAlgorithmName: table_inline shardingAlgorithms: table_inline: type: INLINE props: algorithm-expression: demo_core_sharding_model_${(Long.valueOf(user_id) % 8)} props: sql.show: true 图4-1-24-3 分库分表规则配置 Step3 配置测试入口 修改DemoMenus类增加一行代码,为测试提供入口 @UxMenu("分表模型")@UxRoute(ShardingModel.MODEL_MODEL) class ShardingModelMenu{} 图4-1-24-4 配置测试入口 Step4 重启看效果 自行尝试增删改查 观察数据库表与数据分布 图4-1-24-5 自行尝试增删改查 图4-1-24-6 观察数据库表与数据分布 二、分库分表(举例) Step1 新建ShardingModel2模型 ShardingModel2模型是用于分库分表测试的模型,我们选定userId作为分表字段。分库分表字段不允许更新,所以这里更新策略设置类永不更新,并在设置了在页面修改的时候为readonly package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.boot.base.ux.annotation.field.UxWidget; import pro.shushi.pamirs.boot.base.ux.annotation.view.UxForm; import…

    2024年5月23日
    1.2K00

Leave a Reply

登录后才能评论