前端自定义字段与视图最佳方案

自定义视图获取数据

在某些情况下,oinone 提供的默认视图无法满足需求,这时我们就需要自定义视图。通常,虽然视图的 UI 不足以满足要求,但数据结构是不变的。此时,重点是修改页面 UI,数据的请求与回填可以利用平台默认的能力。

如何实现?

  1. 界面设计器的使用
    1. 你可以通过界面设计器先配置页面,平台在运行时会根据设计器生成对应的 GraphQL 请求,并自动回填数据。
  2. 视图的数据结构
    1. 视图的数据类型分为可以分为 Object 跟 List
      1. Object 代表当前视图的数据结构是对象
      2. List 代表当前视图的数据结构是数组。

如果我们将 Object 跟 List 分的更细一点就变成了这样:

1: Object: 对象,代表当前视图的数据结构是单个对象,例如:表单视图、详情视图
1: List: 对象数组,代表当前视图的数据结构数组,例如:表格视图、卡片视图、画廊视图

视图类型 平台组件 数据属性
表格视图 TableWidget dataSource
画廊视图 GalleryWidget dataSource
表单视图 FormWidget formData
详情视图 DetailWidget formData

自定义视图时,需要先确认当前视图的类型,再通过界面设计器进行页面配置。前端部分只需继承相应的组件,平台底层会自动处理接口数据的获取与回填。

表单视图示例:

import Form from './Form.vue';

// 自定义表单视图
@SPI.ClassFactory(
  BaseElementWidget.Token({
    widget: 'custom-form'
  })
)
export class CustomForm extends FormWidget {
  public initialize(props: Props) {
    super.initialize(props);
    this.setComponent(Form);
    return this;
  }
}

Vue 组件:

<template></template>
<script lang="ts">
export default defineComponent({
  props: {
    formData: {
      // 当前表单的数据
      type: Object,
      default: () => ({})
    }
  }
});
</script>

自定义layout

// 原始的layout模版
<view type="FORM">
    <element widget="actionBar" slot="actionBar" slotSupport="action">
        <xslot name="actions" slotSupport="action" />
    </element>
    <element widget="form" slot="form">
        <xslot name="fields" slotSupport="pack,field" />
    </element>
</view>

//自定义的layout模版
<view type="FORM">
    <element widget="actionBar" slot="actionBar" slotSupport="action">
        <xslot name="actions" slotSupport="action" />
    </element>
    <element widget="custom-form" slot="form">
        <xslot name="fields" slotSupport="pack,field" />
    </element>
</view>

其实就是把 widget="form" 改成 widget="custom-form"

表格视图示例:

import Table from './Table.vue';

// 自定义表格视图
@SPI.ClassFactory(
  BaseElementWidget.Token({
    widget: 'custom-table'
  })
)
export class CustomTable extends TableWidget {
  public initialize(props: Props) {
    super.initialize(props);
    this.setComponent(Table);
    return this;
  }
}

Vue 组件:

<template></template>
<script lang="ts">
export default defineComponent({
  props: {
    dataSource: {
      // 当前列表的数据
      type: Object,
      default: () => ({})
    }
  }
});
</script>

自定义layout

// 原始的layout模版
<view type="TABLE">
    <pack widget="group">
        <view type="SEARCH">
            <element widget="search" slot="search" slotSupport="field">
                <xslot name="searchFields" slotSupport="field" />
            </element>
        </view>
    </pack>
    <pack widget="group" slot="tableGroup">
        <element widget="actionBar" slot="actionBar" slotSupport="action">
            <xslot name="actions" slotSupport="action" />
        </element>
        <element widget="table" slot="table" slotSupport="field">
            <element widget="expandColumn" slot="expandRow" />
            <xslot name="fields" slotSupport="field" />
            <element widget="rowActions" slot="rowActions" slotSupport="action" />
        </element>
    </pack>
</view>

//自定义的layout模版
<view type="TABLE">
    <pack widget="group">
        <view type="SEARCH">
            <element widget="search" slot="search" slotSupport="field">
                <xslot name="searchFields" slotSupport="field" />
            </element>
        </view>
    </pack>
    <pack widget="group" slot="tableGroup">
        <element widget="actionBar" slot="actionBar" slotSupport="action">
            <xslot name="actions" slotSupport="action" />
        </element>
        <element widget="custom-table" slot="table" slotSupport="field">
            <element widget="expandColumn" slot="expandRow" />
            <xslot name="fields" slotSupport="field" />
            <element widget="rowActions" slot="rowActions" slotSupport="action" />
        </element>
    </pack>
</view>

其实就是把 widget="table" 改成 widget="custom-table"

以上代码展示了如何继承对应的 widget,平台会自动调用接口获取数据。如果你需要自定义接口调用,请参考然后参考这篇文章,调用接口

自定义字段获取数据、提交数据

在 oinone 中,常见的自定义字段分为两种,一种是表单字段,一种是列表字段。

表单字段

1.  所有的表单字段都有 value 属性,用来存储当前字段对应的值
2.  所有的表单字段都有 formData 属性,用来获取其他字段的值,也可以修改其他字段的值
3.  所有的表单字段都有 change 方法,用来修改当前字段对应的值

示例:

@SPI.ClassFactory(
  FormFieldWidget.Token({
    viewType: [ViewType.Form, ViewType.Search],
    ttype: ModelFieldType.String
  })
)
export class CustomFormFieldWidget extends FormFieldWidget {
  mounted() {
    console.log(this.value); // 获取当前字段的值
    console.log(this.formData); // 获取当前表单的值
    this.change('hello'); // 修改当前字段的值
  }
}

Vue 组件:

<template>
  <div @click="change('hi')">{{ value }}</div>
</template>
<script lang="ts">
export default defineComponent({
  props: {
    value: {
      type: String
    },
    change: {
      type: Function
    }
  }
});
</script>

列表字段

  1. 所有的列表字段都有 dataSource 属性,用来获取当前列表的数据
  2. 所有的列表字段中的 renderDefaultSlot 方法,用来渲染单元格组件

示例:

@SPI.ClassFactory(
  BaseFieldWidget.Token({
    viewType: ViewType.Table,
    ttype: [ModelFieldType.String, ModelFieldType.Phone, ModelFieldType.Email]
  })
)
export class CustomTableFieldWidget extends BaseFieldWidget {
  @Widget.Method()
  public renderDefaultSlot(context): VNode[] | string {
    const currentValue = this.compute(context) as string[];
    return [createVNode(TableVue, { value: currentValue })];
  }
}

Vue 组件:

// Table.vue
<template>
  <div>{{ value }}</div>
</template>
<script lang="ts">
export default defineComponent({
  props: {
    value: {
      type: String
    }
  }
});
</script>

通过这些自定义实现,你可以灵活地控制视图和字段的数据获取与修改,并且能够利用平台的 GraphQL 能力来实现更简便的数据操作。

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

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

(2)
汤乾华的头像汤乾华数式员工
上一篇 2024年10月16日 pm4:56
下一篇 2024年10月17日 pm9:13

相关推荐

  • 树型表格全量加载数据如何处理

    阅读该文档的前置条件 【界面设计器】树形表格 1.前端自定义表格组件 import { ActiveRecord, BaseElementWidget, Condition, Entity, SPI, TableWidget, ViewType } from '@kunlun/dependencies'; @SPI.ClassFactory( BaseElementWidget.Token({ type: ViewType.Table, widget: ['demo-tree-table'] }) ) export class TreeTableWidget extends TableWidget { // 默认展开所有层级 protected getTreeExpandAll() { return true; } // 关闭懒加载 protected getTreeLazy(): boolean { return false; } public async $$loadTreeNodes(condition?: Condition, currentRow?: ActiveRecord): Promise<Entity[]> { // 树表加载数据的方法,默认首次只查第一层的数据,这里去掉这个查询条件的参数condition,这样就会查所有层级数据 return super.$$loadTreeNodes(undefined, currentRow); } } 2. 注册layout import { registerLayout, ViewType } from '@kunlun/dependencies'; const install = () => { registerLayout( ` <view type="TABLE"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="demo-tree-table" slot="table"> <element widget="expandColumn" slot="expandRow" /> <xslot name="fields" slotSupport="field" /> <element widget="rowActions" slot="rowActions" slotSupport="action" /> </element> </view> `, { viewType: ViewType.Table, model: "resource.resourceCity", // 变量,需要替换 actionName: "MenuuiMenu6f6005bdddba468bb2fb814a62fa83c6", // 变量,需要替换 } ); }; install();

    2024年8月17日
    97000
  • oio-modal 对话框

    API 参数 说明 类型 默认值 版本 cancelText 取消按钮文字 string| slot 取消 closable 是否显示右上角的关闭按钮 boolean true closeIcon 自定义关闭图标 VNode | slot – confirmLoading 确定按钮 loading boolean 无 destroyOnClose 关闭时销毁 Modal 里的子元素 boolean false footer 底部内容,当不需要默认底部按钮时,可以设为 :footerInvisible="true" slot 确定取消按钮 getTriggerContainer 指定 Modal 挂载的 HTML 节点 (instance): HTMLElement () => document.body keyboard 是否支持键盘 esc 关闭 boolean true mask 是否展示遮罩 boolean true maskClosable 点击蒙层是否允许关闭 boolean true enterText 确认按钮文字 string 确定 title 标题 string|slot 无 visible(v-model:visible) 对话框是否可见 boolean 无 width 宽度 string|number 520 wrapClassName 对话框外层容器的类名 string – zIndex 设置 Modal 的 z-index number 1000 cancelCallback 点击遮罩层或右上角叉或取消按钮的回调, return true则关闭弹窗 function(e) enterCallback 点击确定回调 function(e)

    2023年12月18日
    1.1K00
  • 如何在自有前端工程中使用gql请求?

    场景 客户在个性化程度比较高的h5工程中想使用平台的服务端能力,这个时候需要调用后端的gql请求,此时需要引入平台的请求库依赖 npm的package.json中加入依赖 此文档以4.x举例,使用其他版本的请自行修改版本号 "dependencies": { "@kunlun/request": "~4.3.0", "@kunlun/state": "~4.3.0" } 使用示例 import { HttpClient } from ‘@kunlun/request’ const http = HttpClient.getInstance() http.setBaseURL(”) export const login = (data) => { const gqlBody = `mutation { pamirsUserTransientMutation { login(user: {login: “${data.username}”, password: “${data.password}”}) { broken errorMsg errorCode errorField } } }` return http.mutate(‘user’, gqlBody) } 注意事项 开发环境记得配置oinone请求的路由转发规则,这里以vite.config.js举例 import { defineConfig } from ‘vite’ export default defineConfig({ server: { port: 8088, open: true, proxy: { ‘/pamirs’: { changeOrigin: true, // 服务端请求地址 target: ‘http://127.0.0.1:8091’ } } } })

    2023年11月1日
    98100
  • oio-checkbox 对选框

    API 属性 Checkbox 参数 说明 类型 默认值 版本 autofocus 自动获取焦点 boolean false checked(v-model:checked) 指定当前是否选中 boolean false disabled 失效状态 boolean false indeterminate 设置 indeterminate 状态,只负责样式控制 boolean false value 与 CheckboxGroup 组合使用时的值 boolean | string | number – 事件 事件名称 说明 回调参数 版本 change 变化时回调函数 Function(e:Event) –

    2023年12月18日
    83700
  • 【前端】项目开发前端知识要点地图

    概述 下面整理了目前现有的所有文章,并提供了基本的学习路径。所有使用*标记的文章属于推荐必读文章。 目录 基础篇 【路由】浏览器地址栏url参数介绍 母版-布局-DSL 渲染基础(v4)* 组件SPI机制(v4)* 组件数据交互基础(v4)* 组件生命周期(v4) 入门篇 自定义视图组件(v4)* 如何通过浏览器开发者工具提高调试效率* 如何提高自定义组件的开发效率* 自定义组件之自动渲染(组件插槽的使用)(v4)* GraphQL请求详解(v4)* 上下文在字段和动作中的应用 如何实现页面间的跳转 如何自定义指定页面的样式 进阶篇 自定义组件之手动渲染基础(v4) 自定义组件之手动渲染弹出层(v4) 自定义组件之手动渲染任意视图(v4) 【前端】IOC容器(v4) 最佳实践篇 【前端】工程结构最佳实践(v4)* 【前端】移动端工程结构最佳实践(v4)* 界面设计器实战篇 基础篇 【界面设计器】模型增删改查基础 【界面设计器】他表字段 【界面设计器】左树右表 【界面设计器】树形表格 【界面设计器】树下拉/级联选择 【界面设计器】自定义字段组件基础 展示篇 【界面设计器】自定义字段组件实战——轮播图 【界面设计器】自定义字段组件实战——表格字段组合展示 【界面设计器】自定义字段组件实战——表格字段内嵌表格 交互篇 【界面设计器】自定义字段组件实战——千分位输入框 其他 前端低无一体使用教程 如何自定义表格字段? 【界面设计器】组件开发常见问题 【前端】低无一体部署常见问题 【前端】生产环境性能调优 API文档 OioProvider详解(v4.3.0)* 前端环境配置(v4)* 默认布局模板(v4) 表格主题配置(v4) 运行时上下文API文档(v4) Class Component(ts)(v4)

    2024年5月25日
    4.0K00

Leave a Reply

登录后才能评论