PC端、移动端默认Mask模板

PC端

系统默认母版布局

<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>
        <sidebar>
            <widget widget="nav-menu" height="100%" />
        </sidebar>
        <content>
            <breadcrumb />
            <block width="100%">
                <widget width="100%" widget="main-view" />
            </block>
        </content>
    </container>
</mask>

系统默认把多tabs放入视图内母版布局

<mask>
    <header>
        <widget widget="app-switcher" />
        <block>
            <widget widget="notification" />
            <widget widget="divider" />
            <widget widget="language" />
            <widget widget="divider" />
            <widget widget="user" />
        </block>
    </header>
    <container>
        <sidebar>
            <widget widget="nav-menu" height="100%" />
        </sidebar>
        <block height="100%" flex="1 0 0" flexDirection="column" alignContent="flex-start" flexWrap="nowrap" overflow="hidden">
            <multi-tabs inline="true" />
            <content>
                <breadcrumb />
                <block width="100%">
                    <widget width="100%" widget="main-view" />
                </block>
            </content>
        </block>
    </container>
</mask>

移动端

<mask>
  <widget widget="user" />
  <widget widget="nav-menu"  app-switcher="true" menu="true" />
  <widget widget="main-view" height="100%" />
</mask>

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

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

Like (1)
汤乾华's avatar汤乾华数式员工
Previous 2024年12月11日 am10:36
Next 2024年12月11日 am10:57

相关推荐

  • 列表视图、卡片视图切换

    在日常项目开发中,我们可能会遇到当前视图是个表格,通过某个操作按钮将它变成卡片的形式. 这篇文章将带大家实现这种功能。通过上面两张图片可以看到出来不管是表格还是卡片,它都在当前的视图里面,所以我们需要一个视图容器来包裹表格跟卡片,并且表格可以使用平台默认的表格渲染,我们只需要自定义卡片即可。 我们用资源模块下面的国家菜单来实现这么一个功能这是对应的URL: http://localhost:8080/page;module=resource;viewType=TABLE;model=resource.ResourceCountry;action=resource%23%E5%9B%BD%E5%AE%B6;scene=resource%23%E5%9B%BD%E5%AE%B6;target=OPEN_WINDOW;menu=%7B%22selectedKeys%22:%5B%22%E5%9B%BD%E5%AE%B6%22%5D,%22openKeys%22:%5B%22%E5%9C%B0%E5%9D%80%E5%BA%93%22,%22%E5%9C%B0%E5%8C%BA%22%5D%7D 源码下载 views 创建外层的视图容器 刚刚我们讲过,不管是表格还是卡片,它都在当前的视图里面,所以我们需要写一个视图容器来包裹它们,并且对应的容器里面允许拆入表格跟卡片,我们先创建TableWithCardViewWidget.ts // TableWithCardViewWidget.ts import { BaseElementWidget, SPI, Widget } from '@kunlun/dependencies'; import TableWithCardView from './TableWithCardView.vue'; enum ListViewType { TABLE = 'table', CARD = 'card' } @SPI.ClassFactory( BaseElementWidget.Token({ widget: 'TableWithCardViewWidget' }) ) export class TableWithCardViewWidget extends BaseElementWidget { @Widget.Reactive() private listViewType: ListViewType = ListViewType.TABLE; // 当前视图展示的类型,是展示卡片还是表格 public initialize(props) { if (!props.slotNames) { props.slotNames = ['tableWidget', 'cardWidget']; } super.initialize(props); this.setComponent(TableWithCardView); return this; } } 在TableWithCardViewWidget中的initialize函数中,我们定义了两个插槽: tableWidget、cardWidget,所以需要在对应的vue文件里面里接收这两个插槽 <template> <div class="list-view-wrapper"> <!– 表格插槽 –> <div style="height: 100%" v-if="listViewType === 'table'"> <slot name="tableWidget" /> </div> <!– 卡片插槽 –> <div v-if="listViewType === 'card'"> <slot name="cardWidget"></slot> </div> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ props: ['listViewType', 'onChangeViewType'], inheritAttrs: false, setup(props, context) { const onChangeViewType = (listViewType) => { props.onChangeViewType(listViewType); }; } }); </script> 这样一来,我们就定义好了视图容器,接下来就是通过自定义layout的方式注册该容器 layout注册 import { registerLayout, ViewType } from '@kunlun/dependencies'; registerLayout( `<view type="TABLE"> <pack widget="group"> <view type="SEARCH"> <element widget="search" cols="4" slot="search"/> </view> </pack> <pack widget="group" slot="tableGroup" style="position: relative"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="TableWithCardViewWidget"> <template slot="tableWidget"> <element widget="table" slot="table" datasource-provider="true"> <element widget="expandColumn" slot="expandRow" /> <xslot name="fields" />…

    2024年10月16日
    2.9K01
  • oinone的rsql与传统sql语法对照表

    rsql sql 描述 field01 == "name" field01 = "name" 等于 field01 != "name" field01 != "name" 不等于 field01 =gt= 1 field01 > 1 大于 field01 =ge= 1 field01 >= 1 大于等于 field01 =lt= 1 field01 < 1 小于 field01 =le= 1 field01 <= 1 小于等于 field01 =isnull=true field01 is null 字段为null field01 =notnull= 1 field01 is not null 字段不为null field01 =in= ("foo") field01 in ("foo") 多条件 field01 =out= ("foo") field01 not in ("foo") 不在多条件中 field01 =cole= field02 field01 = field02 字段作为查询参数 field01 =colnt= field02 field01 != field02 字段作为查询参数 field01 =like="foo" field01 like "%foo%" 全模糊匹配,rsql语法中无需拼接通配符”%“ field01 =starts="foo" field01 like "foo%" 前缀模糊匹配,rsql语法中无需拼接通配符”%“ field01 =ends="foo" field01 like “%foo" 后缀模糊匹配,rsql语法中无需拼接通配符”%“ field01 =notlike="foo" field01 not like "%foo%" 全模糊不匹配,rsql语法中无需拼接通配符”%“ field01 =notstarts="foo" field01 not like "foo%" 前缀模糊不匹配,rsql语法中无需拼接通配符”%“ field01 =notends="foo" field01 not like “%foo" 后缀模糊不匹配,rsql语法中无需拼接通配符”%“ field01 =has=(ENUM_NAME1, ENUM_NAME2) 有多值枚举中的几个值 field01 =hasnt=(ENUM_NAME1,ENUM_NAME2) 没有多值枚举中的几个值 field01 =bit=ENUM_NAME1 有二进制枚举中的单个值 field01 =notbit=ENUM_NAME1 没有二进制枚举中的单个值 前端代码中使用工具类拼接rsql 该工具类在oinone的前端基础框架中提供 import { Condition } from '@kunlun/dependencies'; const rsqlCondition = new Condition('field01').equal('foo') .and(new Condition('field02').in(['bar'])) .and(new Condition('field03').notIn(['foo'])) .or(new Condition('field04').greaterThanOrEuqalTo(12)) .or(new Condition('field05').like('foo')) .or(new Condition('field06').notStarts('bar')) .or(new Condition('field07').isNull()) .or(new Condition('field08').notNull()) .and(new Condition('field09').bitEqual('BIT_ENUM_1')) .and(new Condition('field10').bitNotEqual('BIT_ENUM_2')) .and(new Condition('field11').has('ENUM_NAME_1')) .and(new Condition('field12').hasNot(['ENUM_NAME_2', 'ENUM_NAME_3'])); const rsqlStr = rsqlCondition.toString();…

    2023年11月1日
    4.5K00
  • 前端自定义左树右表中的树

    在 oinone 平台中,提供了默认的左树右表的视图,用户可以通过界面设计器配置,默认的树视图不一定满足所有需求,尤其当需要自定义功能或复杂的交互时,我们可以通过自定义视图来实现更灵活的展现。 本文将带你一步步了解如何自定义左树右表视图中的树组件。 自定义树视图 1. 使用界面设计器配置视图 首先,我们需要通过界面设计器生成基础的左树右表视图。界面设计器允许用户根据不同需求进行拖拽配置,快速创建可视化界面。 配置完视图之后,我们可以重写左侧的树组件。Oinone 的默认树组件是 TableSearchTreeWidget,通过自定义的方式,我们可以实现更高级的功能。 2. 重写 TableSearchTreeWidget import { BaseElementWidget, SPI, TableSearchTreeWidget, ViewType } from '@kunlun/dependencies'; import CustomTableSearchTree from './CustomTableSearchTree.vue'; @SPI.ClassFactory( BaseElementWidget.Token({ viewType: [ViewType.Table, ViewType.Form], widget: 'tree', model: 'resource.k2.Model0000000100' // 改成自己的模型 }) ) export class CustomTableSearchTreeWidget extends TableSearchTreeWidget { public initialize(props) { super.initialize(props); this.setComponent(CustomTableSearchTree); return this; } } 3. 定义 Vue 树组件 接下来,我们来实现 CustomTableSearchTree.vue 组件。这个组件将处理树的数据加载、节点选中等逻辑。你可以根据项目的需要修改其中的交互逻辑或 UI 设计。 <template> <a-tree :load-data="onLoadData" :tree-data="treeData" @select="onSelected" /> </template> <script lang="ts"> import { OioTreeNode, TreeUtils } from '@kunlun/dependencies'; import { computed, defineComponent } from 'vue'; export default defineComponent({ props: { rootNode: { type: Object }, loadData: { type: Function, required: true }, onSelected: { type: Function, required: true } }, setup(props) { // // 计算树的数据源,使用 TreeUtils 处理 const treeData = computed(() => { return TreeUtils.fillLoadMoreAction([…(props.rootNode?.children || [])]); }); // 异步加载子节点 const onLoadData = async (node) => { return await props.loadData(node.dataRef); }; // 处理节点选中事件 const onSelected = ( selectedKeys: string[], e: { nativeEvent: PointerEvent; node: { dataRef: OioTreeNode }; selected: boolean } ) => { props.onSelected?.(e.node.dataRef, e.selected); }; return { treeData, onLoadData, onSelected }; } }); </script> 4. 自定义…

    2024年10月21日
    3.4K00
  • 前端自定义请求入门版

    在开发过程中,为了满足业务场景、增加灵活性,前端自定义请求不可避免。下面将会从——自定义 mask、自定义表格(表单等)、自定义字段三个实际场景的角度,介绍自定义请求。这篇文章把请求都写在了 ts 中,这样便于继承重写,如果不习惯 ts 的写法,把请求写在 vue 里也是可以的。 1. 自定义 mask mask 组件通常会有一个特点:在不同页面不同模型或不同应用下都展示,与业务模型无关,且往往只需要请求一次。同时可能有精确控制请求体大小的需求,这就很适合采取手写 GraphQL 的方式。 例如,我要重写顶部 mask 中的用户组件,展示用户信息。这个请求就只需请求一次,而且不需要复用,就很适合手写 GraphQL。 这里继承平台的用户组件,然后在代码中写死 GraphQL 发起请求。但是 GraphQL 语句怎么拼呢?我们可以去默认页面,打开浏览器控制台,找到相应的请求,把 GraphQL 语句复制出来,这里复制下默认的用户请求。 http.query 参数的构造、相应结果的获取都能从请求中得到。可以看到我这里精简了请求,只取了用户名。 TS import { SPI, UserWidget, MaskWidget, Widget, http } from '@kunlun/dependencies'; import Test from './Test.vue'; @SPI.ClassFactory(MaskWidget.Token({ widget: 'user' })) export class TestWidget extends UserWidget { public initialize(props) { super.initialize(props); this.setComponent(Test); return this; } // 添加响应式注解,这样能在 vue 中接受到 ts 中的变量 @Widget.Reactive() public testUserInfo: { pamirsUser: { name: string } } | undefined; public async queryUser() { const query = ` { topBarUserBlockQuery { construct(data: {}) { pamirsUser { name } } } } `; const result = await http.query('user', query); this.testUserInfo = result.data['topBarUserBlockQuery']['construct'] as { pamirsUser: { name: string } }; } public mounted() { this.queryUser(); } } VUE <template> <div class="Test"> {{ testUserInfo }} </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ name: 'Test', props: ['testUserInfo'] }); </script> 效果如下: 2. 自定义表格(表单)等视图元素组件 2-1. 自定义表格 2-1-1. 自定义表格自动获取数据 Oinone 提供了前端组件的默认实现。所以生成默认页面的时候,请求数据都是通的,可以看到表格、表单、表单里的字段等组件数据都是能回填的。所以这里继承平台的表格组件,就有了平台表格自动获取数据的能力。 TS import { BaseElementWidget, SPI, TABLE_WIDGET, TableWidget, ViewType } from '@kunlun/dependencies'; import Test from './Test.vue'; @SPI.ClassFactory( BaseElementWidget.Token({ viewType: ViewType.Table, widget:…

    2025年4月17日
    84600
  • 前端打包文件上传到oss

    打包dist文件上传到oss教程 1: 确保boot工程里面安装了「webpack-aliyun-oss」依赖, 如果没有安装,可以手动安装下 2: package.json -> devDependencies -> {"webpack-aliyun-oss": "0.5.2"} 3: 在vue.config.js文件中添加对应的plugin // vue.config.js文件 // 新增代码 let BASE_URL = '/'; const { DEPLOY, OSS_REGION, OSS_DIST, OSS_URL, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, OSS_BUCKET } = process.env; const UNIQUE_KEY = Math.random(); switch (DEPLOY) { case 'online': BASE_URL = `${OSS_URL}${UNIQUE_KEY}/`; break; default: BASE_URL = '/'; } module.exports = { …原先的代码, publicPath: BASE_URL, plugins: [ …原先的插件, DEPLOY === 'online' ? new WebpackAliyunOss({ from: ['./dist/**/**', '!./dist/**/*.html'], // build目录下除html之外的所有文件 dist: `${OSS_DIST}/${UNIQUE_KEY}`, // oss上传目录 region: OSS_REGION, // 地区, 比如 oss-cn-hangzhou accessKeyId: OSS_ACCESS_KEY_ID, accessKeySecret: OSS_ACCESS_KEY_SECRET, bucket: OSS_BUCKET, timeout: 1200000, deleteOrigin: true, deleteEmptyDir: true, overwrite: true }) : () => {} ] } 4: 在vue.config.js同级目录下面新增「.env」文件, 写入对应的配置, 配置对应的值按照自己的oss配置来 DEPLOY=online OSS_BUCKET=xxx OSS_DIST=/oinone/product OSS_URL=https://xxxxxx/oinone/product/ OSS_REGION=oss-cn-hangzhou OSS_ACCESS_KEY_ID=xxxx OSS_ACCESS_KEY_SECRET=xxxx

    2023年11月1日
    2.1K00

Leave a Reply

Please Login to Comment