3.5.7.8 自定义菜单栏

在业务中,可能会遇到需要对菜单栏的交互或UI做全新设计的需求,这个时候可以自定义菜单栏组件支持。

首先继承平台的CustomMenuWidget 组件,将自己vue文件设置到component处

import { NavMenu, SPI, ViewWidget } from '@kunlun/dependencies';
import Component from './CustomMenu.vue';

@SPI.ClassFactory(
  ViewWidget.Token({
    // 这里的widget跟平台的组件一样,这样才能覆盖平台的组件
    widget: 'nav-menu'
  })
)
export class CustomMenuWidget extends NavMenu {

  public initialize(props) {
    super.initialize(props);
    this.setComponent(Component);
    return this;
  }
}

vue文件中继承平台的props,编写自定义页面代码

export const NavMenuProps = {
  /**
   * 当前模块
   */
  module: {
    type: Object as PropType<IModule | null>
  },
  /**
   * 树结构的菜单
   */
  menus: {
    type: Array as PropType<IResolvedMenu[]>,
    default: () => []
  },
  /**
   * 菜单类型,现在支持垂直、水平、和内嵌模式三种
   */
  mode: {
    type: String as PropType<'vertical' | 'horizontal' | 'inline'>,
    default: 'inline'
  },
  /**
   * 菜单栏是否折叠收起
   */
  collapsed: {
    type: Boolean,
    default: false
  },
  /**
   * 当前展开的 SubMenu 菜单项 key 数组
   */
  openKeys: {
    type: Array as PropType<string[]>,
    default: () => []
  },
  /**
   * 当前选中的菜单项 key 数组
   */
  selectKeys: {
    type: Array as PropType<string[]>,
    default: () => []
  },
  /**
   * 菜单搜索下拉选中菜单项
   */
  selectMenuBySearch: {
    type: Function as PropType<(menuName: String) => void>
  },
  /**
   * 选中菜单项
   */
  selectMenu: {
    type: Function as PropType<(menuName: String) => Promise<void>>
  },
  /**
   * SubMenu 展开/关闭的回调
   */
  openChange: {
    type: Function as PropType<(openKeys: string[]) => void>
  },
  /**
   * 菜单栏折叠的回调
   */
  onChangeCollapsed: {
    type: Function as PropType<(collapsed: boolean) => Promise<void>>
  }
};
<template>
  <div class="k-oinone-menu-wrapper custom-menu">
    <div class="menu-search" v-if="module && mode === 'inline' && !collapsed">
      <a-select
        ref="menuSelectSearch"
        dropdown-class-name="ui-designer-select-global"
        option-filter-prop="label"
        placeholder="搜索菜单"
        :show-search="true"
        @change="innerSearchSelect"
      >
        <a-select-option
          v-for="opt in module.allMenus.filter((_f) => _f.viewAction)"
          :key="opt.name"
          :value="opt.name"
          :label="opt.displayName"
        >
          {{ opt.displayName }}
        </a-select-option>
        <template #suffixIcon>
          <oio-icon icon="oinone-sousuo" size="14px" color="var(--oio-menu-default-icon-color)" />
        </template>
      </a-select>
    </div>
    <div class="menu-area oio-scrollbar">
      <div class="menu-content" :class="collapsed && 'collapsed'">
        <template v-for="item in menus" :key="item.key">
          <template v-if="!item.children || !item.children.length">
            <div :key="item.key" :title="item.title" class="root-menu" @click="selectMenu(item.key)">
              {{ item.title }}
            </div>
          </template>
          <template v-else>
            <div class="menu-group">
              <div class="root-menu" :title="item.title">{{ item.title }}</div>
              <div class="sub-menus">
                <template v-for="subItem in item.children" :key="subItem.key">
                  <div class="sub-menu" :title="subItem.title" @click="selectMenu(subItem.key)">
                    {{ subItem.title }}
                  </div>
                </template>
              </div>
            </div>
          </template>
        </template>
      </div>
    </div>

    <div class="menu-footer" :class="collapsed && 'collapsed'">
      <div class="menu-toggle-collapsed" @click="onChangeCollapsed(!collapsed)">
        <span class="collapsed-icon">
          <oio-icon
            :icon="collapsed ? 'oinone-menu-caidanzhankai' : 'oinone-menu-caidanshouqi'"
            size="16px"
            color="var(--oio-menu-default-icon-color)"
          />
        </span>
        <span v-show="!collapsed" class="collapsed-text">点击收起菜单</span>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, nextTick } from 'vue';
import { OioIcon, NavMenuProps } from '@kunlun/dependencies';

export default defineComponent({
  props: {
    ...NavMenuProps
  },
  components: {
    OioIcon
  },
  setup(props) {
    const DEFAULT_MENU_ICON = 'oinone-menu-caidanmoren';

    onMounted(async () => {
      await nextTick();
      props.onChangeCollapsed?.(false);
    });

    const menuSelectSearch = ref();
    const innerSearchSelect = (menuName) => {
      props.selectMenuBySearch?.(menuName);
      menuSelectSearch.value?.blur?.();
    };
    return {
      DEFAULT_MENU_ICON,
      menuSelectSearch,
      innerSearchSelect
    };
  }
});
</script>
<style lang="scss">
.custom-menu {
  .root-menu,
  .sub-menu {
    text-indent: 12px;
    cursor: pointer;
    &:hover {
      background: rgba(var(--oio-primary-color-rgb), 0.1);
    }
  }
  .sub-menus {
    padding-left: 20px;
  }
}
</style>

文件目录结构如下图

image.png

最后再到运行路径中导入该组件

这里以启动工程的 main.ts 举例,如果运行时未看到该组件的效果,请检查是否正确导入到运行时的路径中

image.png

以上自定义菜单栏的页面效果如下(该组件仅供演示,所以未实现3级菜单,可自行用子组件实现)

image.png

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

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

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年5月23日 am9:07
Next 2024年5月23日 am9:09

相关推荐

  • 2.4 Oinone的三大独特性

    Oinone在技术方面通过整合互联网架构和低代码技术,实现了三个独特的关键创新点(如图2-5所示): 独立模块化的个性化定制:每个需求都可以被视为一个独立的模块,从而实现个性化定制,提高软件生产效率。此外,这些独立模块也不会影响产品的迭代和升级,为客户带来无忧的体验。 灵活的部署方式:单体部署和分布式部署的灵活切换,为企业业务的发展提供了便利,同时适用于不同规模的公司,有助于有效地节约企业成本,提升创新效率,并让互联网技术更加亲民。 低代码和无代码的结合:低无一体为不同的IT组织和业务用户提供了有效的协同工作方式,能够快速部署安全、可扩展的应用程序和解决方案,帮助企业/组织更好地管理业务流程并不断优化。 图2-5 Oinone的三大独特性

    2024年5月23日
    2.0K00
  • 第3章 Oinone的基础入门

    本章主要介绍如何快速入门,了解如何在Oinone上进行开发。我们将通过准备环境、构建自己的第一个Oinone模块、完成一些小功能等方式来全面了解Oinone,这将是一个很好的开始。 具体来说,本章包括以下几个方面: 环境搭建:准备Windows或Mac版环境。 Oinone以模块为组织:了解Oinone模块的概念和如何创建和使用模块。 Oinone以模型为驱动:了解Oinone模型的概念和如何使用模型来构建应用。 Oinone以函数为内在:了解Oinone函数的概念和如何使用函数来实现应用逻辑。 Oinone以交互为外在:了解Oinone交互的概念和如何使用交互来设计和实现应用界面。

    Oinone 7天入门到精通 2024年5月23日
    2.6K00
  • 7.1 设计器总览

    设计器转为非专业研发设计,在Oinone3.0版本中已经完成元数据完整在线化,真正做到低无一体。对于设计器的定位我们开篇就介绍过,它是LCDP的产品化呈现,是冰山露在外面大家看得到的,核心还是在LCDP本身。我们先目睹下设计器的一些产品页面,如您有想体验,可以在Oinone官网注册 模型设计器 Oinone以模型为驱动,当有模型、数据字典、数据编码等设计功能,我们就可以完整地定义产品数据模型,模型设计器整体呈现区别于普通ER图,以当前模型为核心视角展开,可以点击关联模型切换主视角。这样的好处在于突出当前设计,聚焦设计本身。同时模型上预留了几个核心入口如:分类管理、继承拓扑图、页面设计、逻辑设计等。另外我们在体验上区分了专家模式和经典模式,顾名思义,专家模式的功能会更加丰富,对专业知识的要求也会更高。专家模式下一般会增加一些跟业务无关的配置如:索引设置等调优行为 逻辑设计器 从图灵完备的角度上说,要支持功能越完备,使用越复杂。我们优先从图灵完备的角度出发,所以我们第一版逻辑设计器相对比较复杂,第二版本规划中会类似模型设计器推出专家版和经典版。 界面设计器 界面设计器第一版会先支撑后端页面在线自定义,后边将陆续推出前端页面、多端能力。为了支持多端和2C页面的设计,我们对前后端协议做了比较大的改造。目前设计器已经支持完全基于V3的前后端协议。 数据可视化 数据可视化支持从内部系统模型获取数据内容后,根据业务需求自定义图表,目的是为企业提供更高效的数据分析工具。 与市场同类产品相比,我们的数据可视化产品:不需要前置维护数据源、进行数据转换;可智取业务系统模型,系统自动解析选择的模型、接口、表格中的字段后进行数据分析;降低对数据分析人员研发能力要求的同时,也提升了数据分析的效率。 流程设计器 Oinone流程设计器为业务流程和审批流程提供了可自动执行的流程模型:通过定义流转过程中的各个动作、规则,以此实现流程自动化。在Oinone流程设计器中,流程可以跨应用设计,不同应用的模型之间可以通过同一流程执行。

    2024年5月23日
    1.9K00

Leave a Reply

Please Login to Comment