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 PropType<(tab: MultiTab) => void>
  },
  /**
   * 关闭当前tab右侧的所有tab
   */
  onCloseRightTabs: {
    type: Function as PropType<(tab: MultiTab) => void>
  },
  /**
   * 新窗口打开当前tab
   */
  onOpenCurrentTabOnNewWindow: {
    type: Function as PropType<(tab: MultiTab) => void>
  }
};
<template>
  <div class="k-layout-multi-tabs-main-area" v-if="tabs && tabs.length && !invisible">
    <div id="k-layout-multi-tabs" class="k-layout-multi-tabs oio-scrollbar">
      <div
        v-for="(tab, index) in tabs"
        :key="tab.key"
        :id="`k-layout-multi-tabs-tab-${index}`"
        class="k-layout-multi-tabs-tab"
        :class="{
          'k-layout-multi-tabs-tab-active': activeTab && tab.key === activeTab.key,
          'active-left-hover': activeTabLeftHoverTab,
          'k-layout-multi-tabs-tab-closable': allowClosable
        }"
        @click="onClickTab(tab)"
        @mouseenter="onMouseenterTab(tab)"
        @mouseleave="onMouseleaveTab(tab)"
      >
        <div class="first-tab-icon" v-if="index === 0">
          <oio-icon icon="oinone-shouye1" />
        </div>
        <div class="k-layout-multi-tabs-tab-title" :title="tab.title">{{ tab.title }}</div>
        <div class="close-button-area" :class="[index === 0 && 'k-layout-multi-tabs-tab-close-btn']">
          <oio-button type="link" @click.stop.prevent="onCloseCurrentTab">
            <oio-icon icon="oinone-guanbi" size="16px" />
          </oio-button>
        </div>
        <div class="split-area" v-if="!isInvisibleSplit(index)"></div>
      </div>
    </div>
    <div class="k-layout-multi-tabs-tools">
      <oio-dropdown trigger="click" overlay-class-name="top-bar-common-dropdown">
        <oio-icon icon="oinone-xiala2" size="16px" />
        <template #overlay>
          <div class="multi-tab-tool-overlay">
            <span
              v-for="item in TabToolItems"
              :key="item.key"
              :class="['multi-tab-tool-overlay-item', isTabToolItemDisable(item) && 'disabled']"
              @click="onTabToolItemClick(item)"
            >
              {{ item.title }}
            </span>
          </div>
        </template>
      </oio-dropdown>
    </div>
  </div>
</template>
<script lang="ts">
import { computed, defineComponent, watch } from 'vue';
import { MultiTabsProps, OioIcon, TabToolItems } from '@kunlun/dependencies';
import { OioButton, OioDropdown } from '@kunlun/vue-ui-antd';

export default defineComponent({
  name: 'MyMultiTabs',
  inheritAttrs: false,
  components: { OioButton, OioDropdown, OioIcon },
  props: {
    ...MultiTabsProps
  },
  setup(props) {
    const activeTabLeftHoverTab = computed(() => {
      return (
        props.activeTab &&
        props.hoverTab &&
        props.activeTab.currentIndex !== undefined &&
        props.hoverTab.currentIndex !== undefined &&
        props.activeTab.currentIndex + 1 === props.hoverTab.currentIndex
      );
    });

    watch(
      () => props.activeTab,
      () => {
        setTimeout(() => {
          if (props.activeTab && props.activeTab.currentIndex) {
            const tabDoc = document.getElementById(`k-layout-multi-tabs-tab-${props.activeTab.currentIndex}`);
            if (tabDoc) {
              tabDoc.scrollIntoView(false);
            }
          }
        }, 10);
      }
    );

    const allowClosable = computed(() => (props.tabs?.length || 0) >= 2);

    function isInvisibleSplit(index: number) {
      if (
        props.hoverTab &&
        props.hoverTab.currentIndex !== undefined &&
        (props.hoverTab.currentIndex === index || props.hoverTab.currentIndex - 1 === index)
      ) {
        return true;
      }
      if (props.activeTab && props.activeTab.currentIndex !== undefined && props.activeTab.currentIndex >= 0) {
        return props.activeTab.currentIndex === index || props.activeTab.currentIndex - 1 === index;
      }
      return false;
    }

    function isTabToolItemDisable(tabToolItem) {
      return tabToolItem.disabled(props.tabs?.length || 0, props.activeTab ? props.activeTab.currentIndex : -1);
    }

    function onTabToolItemClick(tabToolItem) {
      if (isTabToolItemDisable(tabToolItem)) {
        return null;
      }
      props.activeTab && props[tabToolItem.key]?.(props.activeTab);
    }

    return {
      activeTabLeftHoverTab,
      allowClosable,
      TabToolItems,
      isInvisibleSplit,
      isTabToolItemDisable,
      onTabToolItemClick
    };
  }
});
</script>

文件目录结构如下图

image.png

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

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

image.png

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

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

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

相关推荐

  • 3.5.2.3 构建View的Layout

    在日常需求中也经常需要调整Layout的情况,如出现树表结构(左树右表、级联),我们则需要通过修改View的Layout来完成。今天就带您学习下Layout的自定义 第一个表格Layout 如果我们想去除表格视图区域的搜索区、ActionBar(操作区),就可以为视图自定义一个简单的Layout就行啦 Step1 新建一个表格的Layout 在views/demo_core/layout路径下增加一个名为sample_table_layout.xml文件,name设置为sampleTableLayout <view type="TABLE" name="sampleTableLayout"> <!– <view type="SEARCH">–> <!– <pack widget="fieldset">–> <!– <element widget="search" slot="search" slotSupport="field"/>–> <!– </pack>–> <!– </view>–> <pack widget="fieldset" style="height: 100%" wrapperStyle="height: 100%"> <pack widget="row" style="height: 100%; flex-direction: column"> <!– <pack widget="col" mode="full" style="flex: 0 0 auto">–> <!– <element widget="actionBar" slot="actionBar" slotSupport="action">–> <!– <xslot name="actions" slotSupport="action" />–> <!– </element>–> <!– </pack>–> <pack widget="col" mode="full" style="min-height: 234px"> <element widget="table" slot="table" slotSupport="field"> <xslot name="fields" slotSupport="field" /> <element widget="rowAction" slot="rowActions" slotSupport="action"/> </element> </pack> </pack> </pack> </view> 图3-5-2-27 新建一个表格的Layout Step2 修改宠物达人自定义表格Template 在view标签上增加layout属性值为"sampleTableLayout" <view name="tableView" model="demo.PetTalent" cols="1" type="TABLE" enableSequence="true" layout="sampleTableLayout"> ……省略其他 </view> 图3-5-2-28 修改宠物达人自定义表格Template Step3 重启看效果 图3-5-2-29 示例效果 Step4 修改宠物达人自定义表格Template 去除在view标签上的layout属性配置,让其回复正常 第一个树表Layout 本节以“给商品管理页面以树表的方式增加商品类目过滤”为例 Step1 增加商品类目模型 增加PetItemCategory模型继承CodeModel,新增两个字段定义name和parent,其中parent字段M2O关联自身模型,非必填字段(如字段值为空即为一级类目): package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.common.CodeModel; @Model.model(PetItemCategory.MODEL_MODEL) @Model(displayName = "宠物商品类目",summary="宠物商品类目",labelFields={"name"}) public class PetItemCategory extends CodeModel { public static final String MODEL_MODEL="demo.PetItemCategory"; @Field(displayName = "类目名称",required = true) private String name; @Field(displayName = "父类目") @Field.many2one private PetItemCategory parent; } 图3-5-2-30 增加商品类目模型 Step2 修改自定义商品模型 为商品模型PetItem增加一个category字段m2o关联PetItemCategory @Field(displayName = "类目") @Field.many2one private PetItemCategory category; 图3-5-2-31 修改宠物商品模型 Step3 新增名为treeTableLayout的Layout 在views/demo_core/layout路径下增加一个名为tree_table_layout.xml文件,name设置为treeTableLayout 图3-5-2-32 新增名为treeTableLayout的Layout <view type="TABLE" name="treeTableLayout"> <view type="SEARCH"> <pack widget="fieldset"> <element widget="search" slot="search" slotSupport="field"/> </pack> </view> <pack…

    2024年5月23日
    70900
  • 第1章 揭开面纱,理解Oinone

    本章旨在从以下几个维度逐步揭开Oinone的面纱,让大家了解Oinone的初心与愿景,以及它是如何站在软件领域的巨人肩膀上,结合企业数字化转型的深入,形成全新的理念,帮助企业完成数字化转型。 具体来说,本章会从以下四个方面逐一展开: Oinone的初心与愿景:结合中国软件行业的发展与自身职业发展经历,探讨Oinone为何诞生以及其愿景是什么。 Oinone致敬西方软件行业的新贵odoo:介绍Oinone的灵感来源,探究Oinone与odoo的异同,以及如何从odoo中汲取经验。 从企业转型困境,引出Oinone新的思路:通过剖析企业数字化转型的困境,引出Oinone提出的全新思路,以及如何应对企业数字化转型的挑战。 行业对比,让您从不同视角理解Oinone:通过与同行业产品进行对比,从不同的视角深入理解Oinone的特点和优势。

    Oinone 7天入门到精通 2024年5月23日
    2.0K00
  • 流程触发

    1. 流程触发 新增的流程设计页面默认包含两个节点,一个是流程的触发节点:确定流程开始的条件;另一个是流程结束的节点。 流程触发方式有模型触发、定时触发、日期触发三种方式,未设置流程触发方式时无法继续添加后续流程节点,同时无法进行流程发布,如左下图。触发方式设置完成后,可从左侧菜单栏拖入或流程箭头中的加号点击添加节点动作,如右下图。 1.1 模型触发 模型触发适用于模型中的数据字段变化开始流程的场景,比如员工请假审批流程。 模型触发的场景有数据的增删改,也可以对模型中的单个或多个字段进行条件筛选,若包含更新数据的场景可以设置选择更新字段,只有设置的字段更新才会触发流程,若不设置选择更新字段或者筛选条件,则模型中任一字段发生设置场景的变化时都会触发流程。 1.2 定时触发 定时触发适用于周期性调用流程的场景,比如仓库周期性盘点的流程。 需要设置一个流程第一次执行的时间,配置好循环的周期间隔。特殊的是选择周为周期时,当前周选中的日期也会执行流程。例:开始时间:2022-01-14(周四) 循环周期间隔:1周 自定义设置为周一到周五,则2022-01-15(本周五)也会执行流程操作。 1.3 日期触发 日期触发适用于模型中的日期时间字段引发流程的场景,比如给员工发生日祝福短信的流程。 设置日期触发时,若指定字段只包含日期,则必须要指定时刻,如左下图。例如给员工发生日祝福短信时根据模型中的员工生日数据获取到了执行流程的日期,需要制定开始该流程执行的具体时刻。若指定字段包含日期和时间,则不填写指定时刻时默认按照字段中的时刻开始执行流程,如右下图。例如办理业务后短信回访收集评价时根据模型中的业务完成时间,立即或延时发送短息。

    2024年6月20日
    91800
  • 4.1.7 函数之元数据详解

    介绍Function相关元数据,以及对应代码注解方式。大家还是可以通读下,以备不时之需 如您还不了解Function的定义,可以先看下2.3【oinone独特之源,元数据与设计原则】对Function的描述,本节主要带大家了解Function元数据构成,能让小伙伴非常清楚oinone从哪些维度来描述Function, 一、元数据说明 FunctionDefinition 元素数据构成 含义 对应注解 备注 namespace 函数命名空间 @Fun("") @Model.model("") @Fun或@Model.model name 技术名称 @Function( name=””, scene={}, summary=””, openLevel=FunctionOpenEnum.REMOTE ) scene 可用场景 见:FunctionSceneEnum description 描述 openLevel 开放级别 见:FunctionOpenEnum fun 编码 @Function.fun("") displayName 显示名称 @Function.Advanced( displayName=””, type=FunctionTypeEnum.UPDATE, dataManager=false, language=FunctionLanguageEnum.JAVA, isBuiltin=false, category=FunctionCategoryEnum.OTHER, group=”pamirs”, version=”1.0.0″, timeout=5000, retries=0, isLongPolling=false, longPollingKey=”userId” longPollingTimeout=1 ) type 函数类型默认:4(改) 见 FunctionTypeEnum dataManager 数据管理器函数默认:false language 函数语言默认:DSL 见FunctionLanguageEnum isBuiltin 是否内置函数 默认:false category 分类 默认:OTHER 见:FunctionCategoryEnum group 系统分组 默认:pamirs version 系统版本 默认:1.0.0 timeout 超时时间 默认:5000 retries 重试次数 默认:0 isLongPolling 是否支持long polling,默认false longPollingKey 支持从上下文中获取字段作为key longPollingTimeout long polling超时时间 默认值为1 transactionConfig 事务配置 JSON存储 见TransactionConfig 配置@PamirsTransactional source 来源 系统推断值,见:FunctionSourceEnum extPointList 函数包含扩展点 系统推断值 module 所属模块 系统推断值 bitOptions 位 系统推断值 attributes 属性 系统推断值 imports 上下文引用 系统推断值 context 上下文变量 系统推断值 codes 函数内容 系统推断值 beanName bean名称 系统推断值 rule 前端规则 系统推断值,一般Action.rule传递下来的 clazz 函数位置 系统推断值 method 函数方法 系统推断值 argumentList 函数参数 系统推断值,List<Argument> returnType 返回值类型 系统推断值 表4-1-7-1 FunctionDefinition TransactionConfig 函数事务管理之配置项事务,具体事务使用详见4.1.8【函数之事务管理】一文。 元素数据构成 含义 对应注解 备注 transactionManager 事务管理器 @PamirsTransactional( transactionManager=””, enableXa=false, isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED, timeout=-1, readOnly=false, rollbackFor={}, rollbackForClassName={}, noRollbackFor={}, noRollbackForClassName={}, rollbackForExpCode={}, noRollbackForExpCode={} ) enableXa 分布式事务默认为false isolation 事务隔离级别 propagation 事务传递类型 timeout 过期时间 默认:-1 readOnly 只读 默认:false rollbackForExpCode 回滚异常编码 rollbackForExpCode 忽略异常编码 namespace 函数命名空间 系统推断值 fun 函数编码 系统推断值 active…

Leave a Reply

登录后才能评论