Class Component(ts)(v4)

Class Component

一种使用typescript的class声明组件的方式。

IWidget类型声明

IWidget是平台内所有组件的统一接口定义,也是一个组件定义的最小集。

/**
 * 组件构造器
 */
export type WidgetConstructor<Props extends WidgetProps, Widget extends IWidget<Props>> = Constructor<Widget>;

/**
 * 组件属性
 */
export interface WidgetProps {
  [key: string]: unknown;
}

/**
 * 组件
 */
export interface IWidget<Props extends WidgetProps = WidgetProps> extends DisposableSupported {
  /**
   * 获取当前组件响应式对象
   * @return this
   */
  getOperator();

  /**
   * 组件初始化
   * @param props 属性
   */
  initialize(props: Props);

  /**
   * 创建子组件
   * @param constructor 子组件构造器
   * @param slotName 插槽名称
   * @param props 属性
   * @param specifiedIndex 插入/替换指定索引的子组件
   */
  createWidget<ChildProps extends WidgetProps = WidgetProps>(
    constructor: WidgetConstructor<ChildProps, IWidget<ChildProps>>,
    slotName?: string,
    props?: ChildProps,
    specifiedIndex?: number
  );
}

Widget

Widget是平台实现的类似于Class Component组件抽象基类,定义了包括渲染、生命周期、provider/inject、watch等相关功能。

export abstract class Widget<Props extends WidgetProps = WidgetProps, R = unknown> implements IWidget<Props> {
  /**
   *  添加事件监听
   *
   * @param  {string} path 监听的路径
   * @param  {deep?:boolean;immediate?:boolean} options?
   *
   * @example
   *
   * @Widget.Watch('formData.name', {deep: true, immediate: true})
   * private watchName(name: string) {
   *   ... todo
   * }
   *
   */
  protected static Watch(path: string, options?: { deep?: boolean; immediate?: boolean });

  /**
   * 可以用来处理不同widget之间的通讯,当被订阅的时候,会将默认值发送出去
   *
   * @param  {Symbol} name 唯一标示
   * @param  {unknown} value? 默认值
   *
   * @example
   *
   * const identifier = Symbol('example-sub')
   *
   * * field.ts * // 文件
   *
   * @Widget.BehaviorSubContext(identifier, {value: '这是默认值'})
   * private exampleSub!:WidgetBehaviorSubjection<{value: string}>
   *
   * onValueChange() {
   *   this.exampleSub.subject.next({value: '这是新的值'})
   * }
   *
   * * other-field.ts * // 文件
   * @Widget.BehaviorSubContext(identifier, {value: '这是默认值'})
   * private exampleSub!:WidgetBehaviorSubjection<{value: string}>
   *
   * mounted() {
   *  this.exampleSub.subscribe((value) => {
   *    ...todo
   *  })
   * }
   *
   */
  protected static BehaviorSubContext(name: Symbol, value?: unknown);

  /**
   * 与 `BehaviorSubContext` 一样,区别在于第一次不会发射默认值
   *
   * @param  {Symbol} name 唯一标示
   * @param  {unknown} value? 默认值
   */
  protected static SubContext(name: Symbol, value?: unknown);

  /**
   * 将数据绑定为响应式,并且组件中可以获取该值
   */
  protected static Reactive(params?: { displayName?: string; render?: boolean });

  /**
   * 将方法绑定为能够被组件获取的方法
   */
  protected static Method(displayName?: string);

  /**
   * 获取上级注入的依赖,与 Provide 一起使用
   *
   * @param  {string|Symbol} injectName? 被注入的name,如果不传递,那么取target中的name
   *
   * @example
   *
   * * children.ts * // 文件
   *
   * @Widget.Inject('InjectName')
   * private rootData!:
   *
   * 如果要将该值变为响应式,如果加上Reactive
   *
   *  @Widget.Reactive()
   *  @Widget.Inject('InjectName')
   *  private rootData!:;
   */
  protected static Inject(injectName?: string | Symbol);

  /**
   * 获取下级注入的依赖,与 Inject 一起使用
   *
   * @param  {string|Symbol} provideName? 被注入的name,如果不传递,那么取target中的name
   *
   * @example
   *
   * * parent.ts * // 文件
   *
   * @Widget.Provide('ProvideName')
   * private rootData!:
   *
   * 如果要将该值变为响应式,如果加上Reactive
   *
   *  @Widget.Reactive()
   *  @Widget.Provide('ProvideName')
   *  private rootData!:;
   */
  protected static Provide(provideName?: string | Symbol);

  /**
   * 通过唯一键获取对应组件
   * @param handle 唯一键
   */
  public static select(handle: string): Widget | undefined;

  public constructor(handle?: string);

  /**
   * 获取当前组件响应式对象
   */
  public getOperator();

  /**
   * 组件初始化
   * @param props 属性
   */
  public initialize(props: Props = {} as Props);

  /**
   * 获取组件唯一键
   */
  public getHandle(): string;

  /**
   * 创建一个widget
   *
   * @param constructor 对应的widget
   * @param name 插槽
   * @param config widget中initialize方法接收的参数
   * @param specifiedIndex 插入到对应位置的索引
   */
  public createWidget<T extends Widget>(
    constructor: WidgetConstructor<T['config'], T>,
    name?: string,
    config?: T['config'],
    specifiedIndex?: number
  );

  /**
   * 销毁当前widget
   */
  public dispose();

  /**
   * 获取父widget
   */
  public getParent(): Widget | undefined;

  /**
   * 获取所有的children
   */
  public getChildren(): Widget[];

  /**
   * 组件渲染
   * @param args 任意渲染参数
   * @return 框架VDom
   */
  public abstract render(...args): R;

  /**
   * beforeCreated 钩子函数
   * @protected
   */
  protected beforeCreated(): void;

  /**
   * created 钩子函数
   * @protected
   */
  protected created(): void;

  /**
   * beforeMount 钩子函数
   * @protected
   */
  protected beforeMount(): void;

  /**
   * mounted 钩子函数
   * @protected
   */
  protected mounted(): void;

  /**
   * beforeUpdate 钩子函数
   * @protected
   */
  protected beforeUpdate(): void;

  /**
   * updated 钩子函数
   * @protected
   */
  protected updated(): void;

  /**
   * activated 钩子函数
   * @protected
   */
  protected activated(): void;

  /**
   * deactivated 钩子函数
   * @protected
   */
  protected deactivated(): void;

  /**
   * beforeUnmount 钩子函数
   * @protected
   */
  protected beforeUnmount(): void;

  /**
   * unmounted 钩子函数
   * @protected
   */
  protected unmounted(): void;
}

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

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

Like (0)
oinone's avataroinone
Previous 2023年6月20日 pm4:07
Next 2023年11月2日 pm1:58

相关推荐

  • 左树右表默认选择第一行

    import { BaseElementWidget, Widget, SPI, ViewType, TableSearchTreeWidget } from '@kunlun/dependencies'; @SPI.ClassFactory( BaseElementWidget.Token({ viewType: ViewType.Table, widget: 'tree', model: '改成当前视图的模型' }) ) export class CustomTableSearchTreeWidget extends TableSearchTreeWidget { protected hasExe = false; @Widget.Watch('rootNode.children.length') protected watchRootNode(len) { if (len && !this.hasExe) { this.hasExe = true; const firstChild = this.rootNode?.children?.[0]; if (firstChild) { this.onNodeSelected(firstChild); this.selectedKeys = [firstChild.key]; } } } }

    2024年11月26日
    1.5K00
  • 表格字段API

    BaseTableFieldWidget 表格字段的基类. 示例 class MyTableFieldClass extends BaseTableFieldWidget{ } 内置常见的属性 dataSource 当前表格数据 rootData 根视图数据 activeRecords 当前选中行 userPrefer 用户偏好 width 单元格宽度 minWidth 单元格最小宽度 align 内容对齐方式 headerAlign 头部内容对齐方式 metadataRuntimeContext 当前视图运行时的上下文,可以获取当前模型、字段、动作、视图等所有的数据 urlParameters 获取当前的url field 当前字段 详细信息 用来获取当前字段的元数据 model 当前模型 详细信息 用来获取当前模型的元数据 view 当前视图 详细信息 界面设计器配置的视图dsl disabled 是否禁用 详细信息 来源于界面设计器的配置 invisible 当前字段是否不可见 详细信息 来源于界面设计器的配置,true -> 不可见, false -> 可见 required 是否必填 详细信息 来源于界面设计器的配置,如果当前字段是在详情页,那么是false readonly 是否只读 详细信息 来源于界面设计器的配置,如果当前字段是在详情页、搜索,那么是false label 当前字段的标题 详细信息 用来获取当前字段的标题 内置常见的方法 renderDefaultSlot 渲染单元格内容 示例 @Widget.Method() public renderDefaultSlot(context): VNode[] | string { // 当前单元格的数据 const currentValue = this.compute(context) as string[]; return [createVNode('div', { class: 'table-string-tag' }, currentValue)]; } renderHeaderSlot 自定义渲染头部 示例 @Widget.Method() public renderHeaderSlot(context: RowContext): VNode[] | string { const children = [createVNode('span', { class: 'oio-column-header-title' }, this.label)]; return children; } getTableInstance 获取当前表格实例(vxe-table) getDsl 获取界面设计器的配置

    2023年11月16日
    1.4K00
  • 如何编写自定义字段组件的校验逻辑

    介绍 自定义字段组件的时候,我们可能会遇到有复杂校验规则或者业务上特殊的校验提示信息的场景,这时候可以通过覆写字段的校验方法validator来实现。 示例代码 import { SPI, ValidatorInfo, FormStringFieldWidget, isEmptyValue, isValidatorSuccess, FormFieldWidget, ViewType, ModelFieldType } from '@kunlun/dependencies' @SPI.ClassFactory(FormFieldWidget.Token({ viewType: [ViewType.Form], ttype: ModelFieldType.String, widget: 'DemoPhone' })) export class DemoFormPhoneFieldWidget extends FormStringFieldWidget { // 字段校验方法 public async validator(): Promise<ValidatorInfo> { // 建议先调用平台内置的通用校验逻辑 const res = await super.validator(); if (!isValidatorSuccess(res)) { // 校验失败直接返回 return res; } // 编写自有校验逻辑 if (!isEmptyValue(this.value) && !/^1[3456789]\d{9}$/.test(this.value as string)) { // 通过内置的validatorError方法提示校验提示信息 return this.validatorError('手机号格式错误'); } // 无异常,用内置的validatorSuccess返回校验通过的信息 return this.validatorSuccess(); } } 扩展学习 自定义字段组件如何处理vue组件内的表单校验

    2024年8月23日
    2.7K00
  • 「前端」获取系统配置

    「前端」获取系统配置 简介 系统配置对于前端开发至关重要,它包含了许多关键信息,通过调用「systemMajorConfig」API,可以轻松地获取这些关键配置信息。除了主要的系统配置外,底层还提供了一些快捷的API,比如获取当前主题、当前主题大小、登录页面主题、版权状态和默认浏览器信息。 使用步骤 调用「systemMajorConfig」API获取系统配置数据。 使用返回的数据对象来访问特定的系统配置参数,如企业名称、企业官网等。 使用底层提供的快捷API来获取与系统配置相关的特定信息。 系统配置参数 logo (string): 应用logo(未折叠状态) appSideLogo (string): 应用logo(折叠状态) smallLogo (string): 小型logo slogan (string): 企业slogan favicon (string): 浏览器logo browserTitle (string): 浏览器标题 loginPageLogo (string): 登录页logo loginBackground (string): 登录页背景 loginLayoutType (any): 登录页布局主题 mode (any): 主题模式 size (string): 主题大小 快捷API列表 getCurrentTheme: 获取当前主题信息。 getCurrentThemeSize: 获取当前主题大小。 getLoginTheme: 获取登录页面主题信息。 getCopyrightStatus: 获取版权状态信息。 getDefaultBrowser: 获取默认浏览器信息。 示例代码 import { systemConfig, getCurrentTheme } from ‘@kunlun/dependencies’ // 访问特定系统配置参数 console.log(systemConfig.logo); // 输出企业名称 // 使用快捷API获取特定信息 console.log(getCurrentTheme());

    2023年11月1日
    1.4K00
  • 函数扩展

    oinone 平台内置了一些函数, 如果当前函数不满足,那么可以通过扩展的方式添加函数 后端实现 后端实现 import {Expression} from '@kunlun/dependencies' Expression.getInstance().registerFunction(); registerFunction函数的参数如下 /** @param {string} name 函数名字 @param {unknown[]} argTypes 参数类型 @param {Function} handle 回调函数 */ 函数名需要跟后端的保持一致import {Expression} from '@kunlun/dependencies';Expression.getInstance().registerFunction('FUNCTION_NAME', ['number|string'], (input: number | string) => { // todo});第二个参数要注意下,该参数跟回调函数里面的参数要保持一致 Expression.getInstance().registerFunction('FUNCTION_NAME', ['number'], (input: number ) => { // todo } ); Expression.getInstance().registerFunction('FUNCTION_NAME', ['string'], (input: string ) => { // todo } ); Expression.getInstance().registerFunction('FUNCTION_NAME', ['array'], (input: any[] ) => { // todo } );

    2023年11月9日
    3.0K00

Leave a Reply

Please Login to Comment