OioProvider详解

OioProvider

OioProvider是平台的初始化入口。

示例入口 main.ts
import { VueOioProvider } from '@kunlun/dependencies';

VueOioProvider();

网络请求/响应配置 http

平台统一使用apollo作为统一的http请求发起服务,并使用GraphQL协议作为前后端协议。

参考文档:

配置方式
VueOioProvider({
  http?: OioHttpConfig
});
OioHttpConfig
/**
 * OioHttp配置
 */
export interface OioHttpConfig {
  /**
   * base url
   */
  url: string;

  /**
   * 拦截器配置
   */
  interceptor?: Partial<InterceptorOptions>;

  /**
   * 中间件配置(优先于拦截器)
   */
  middleware?: NetworkMiddlewareHandler | NetworkMiddlewareHandler[];
}

内置拦截器可选项 InterceptorOptions

/**
 * 拦截器可选项
 */
export interface InterceptorOptions {
  /**
   * 网络错误拦截器
   */
  networkError: NetworkInterceptor;

  /**
   * 请求成功拦截器 (success)
   */
  requestSuccess: NetworkInterceptor;

  /**
   * 重定向拦截器 (success)
   */
  actionRedirect: NetworkInterceptor;

  /**
   * 登录重定向拦截器 (error)
   */
  loginRedirect: NetworkInterceptor;

  /**
   * 请求错误拦截器 (error)
   */
  requestError: NetworkInterceptor;

  /**
   * MessageHub拦截器 (success/error)
   */
  messageHub: NetworkInterceptor;

  /**
   * 前置拦截器
   */
  beforeInterceptors: NetworkInterceptor | NetworkInterceptor[];

  /**
   * 后置拦截器
   */
  afterInterceptors: NetworkInterceptor | NetworkInterceptor[];
}

内置拦截器执行顺序:

  • beforeInterceptors:前置拦截器
  • networkError:网络错误
  • actionRedirect:重定向
  • requestSuccess 请求成功
  • loginRedirect:登录重定向
  • requestError:请求错误
  • messageHub:MessageHub
  • afterInterceptors:后置拦截器

NetworkInterceptor

/**
 * <h3>网络请求拦截器</h3>
 * <ul>
 *   <li>拦截器将按照注册顺序依次执行</li>
 *   <li>当任何一个拦截器返回false时,将中断拦截器执行</li>
 *   <li>内置拦截器总是优先于自定义拦截器执行</li>
 * </ul>
 *
 */
export interface NetworkInterceptor {
  /**
   * 成功拦截
   * @param response 响应结果
   */
  success?(response: IResponseResult): ReturnPromise<boolean>;

  /**
   * 错误拦截
   * @param response 响应结果
   */
  error?(response: IResponseErrorResult): ReturnPromise<boolean>;
}

自定义路由配置 router

配置方式
VueOioProvider({
  router?: RouterPath[]
});
RouterPath
/**
 * 路由配置
 */
export interface RouterPath {
  /**
   * 访问路径
   */
  path: string;
  /**
   * 路由组件名称
   */
  widget: string;
}
内置路由配置
[
  {
    path: '/login',
    widget: 'Login'
  },
  {
    path: '/forget',
    widget: 'ForgetPassword'
  },
  {
    path: '/first',
    widget: 'FirstResetPassword'
  }
]
  • login:登录页路由
  • forget:忘记密码页路由(非登录态)
  • first:首次登录页路由

外观配置

配置方式
VueOioProvider({
  copyrightStatus?: boolean;
  loginTheme?: OioLoginThemeConfig;
  browser?: OioProviderBrowserProps;
  theme?: ThemeName[];
});
copyrightStatus

是否显示copyright信息,默认显示(true)

OioLoginThemeConfig
/**
 * 登录主题配置
 */
export interface OioLoginThemeConfig {
  /**
   * 内置登录主题名称
   */
  name?: OioLoginThemeName;
  /**
   * 背景图片 url
   */
  backgroundImage?: string;
  /**
   * 背景色
   */
  backgroundColor?: string;
  /**
   * logo url
   */
  logo?: string;
  /**
   * 登录页logo显示位置
   */
  logoPosition?: OioLoginLogoPosition;
}

/**
 * 内置登录主题名称
 */
export enum OioLoginThemeName {
  /**
   * 大背景居左登录
   */
  LEFT_STICK = 'LEFT_STICK',
  /**
   * 大背景居右登录
   */
  RIGHT_STICK = 'RIGHT_STICK',
  /**
   * 大背景居中登录
   */
  CENTER_STICK = 'CENTER_STICK',
  /**
   * 大背景居中登录,logo在登录页里面
   */
  CENTER_STICK_LOGO = 'CENTER_STICK_LOGO',
  /**
   * 左侧登录
   */
  STAND_LEFT = 'STAND_LEFT',
  /**
   * 右侧登录
   */
  STAND_RIGHT = 'STAND_RIGHT'
}

/**
 * 登录页logo显示位置
 */
export enum OioLoginLogoPosition {
  /**
   * 左侧
   */
  LEFT = 'LEFT',
  /**
   * 右侧
   */
  RIGHT = 'RIGHT',
  /**
   * 中间
   */
  CENTER = 'CENTER'
}
OioProviderBrowserProps
/**
 * 浏览器配置
 */
export interface OioProviderBrowserProps {
  /**
   * 浏览器选项卡图标
   */
  favicon?: string;
  /**
   * 浏览器默认标题(仅用于非主页面)
   */
  title?: string;
}
ThemeName
type ThemeName =
  | 'default-large'
  | 'default-medium'
  | 'default-small'
  | 'dark-large'
  | 'dark-medium'
  | 'dark-small'
  | string;
  • default-large:默认大号主题
  • default-medium:默认中号主题(默认)
  • default-small:默认小号主题
  • dark-large:深色大号主题
  • dark-medium:深色中号主题
  • dark-small:深色小号主题
  • 其他:自定义主题
定义自定义主题
export const themeName = 'customTheme';

export const themeCssVars = {
  ......
};

主题变量参考文档:OioThemeCssVars

应用自定义主题
import { registerTheme } from '@kunlun/dependencies';
import { themeName, themeCssVars } from './theme';

registerTheme(themeName, themeCssVars);

VueOioProvider({
  theme: [themeName]
});

低无一体依赖配置 dependencies

配置方式
VueOioProvider({
  dependencies?: PluginLoadDependencies
});
PluginLoadDependencies
/**
 * 插件加载依赖
 */
export type PluginLoadDependencies = Record<string, unknown> | PluginLoadDependency[];

/**
 * 插件加载类型
 */
export type PluginLoadType = 'esm' | 'cjs' | 'umd' | 'iife' | 'css';

/**
 * 插件加载依赖
 */
export type PluginLoadDependency = {
  /**
   * 插件加载类型
   */
  type: PluginLoadType;
  /**
   * 依赖项
   */
  dependencies: Record<string, unknown>;
};

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

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

Like (0)
汤乾华's avatar汤乾华数式员工
Previous 2023年11月6日 pm2:34
Next 2023年11月6日 pm2:39

相关推荐

  • 从一个方法开始:浅析页面渲染流程

    渲染前的准备 渲染前的准备,在 Vue 渲染框架下,会先安装所有所支持的默认组件,比如 Mask,Header 等,这些组件支持 XML 默认模版的 Vue 框架下的渲染,详情可见 main.ts 中,maskInstall 与 install,这两个函数将平台内部支持的组件进行了注册,随后将整个 Vue 挂载为运行时 App,随后进行初始化。 渲染的起步 OioProvider 方法是整个应用的入口,我们忽略掉一些配置方法,将注意力集中到 initializeServices 从名称中我们可以看出来内部保存的都是初始化服务,其中提供了渲染服务等,我们当前使用的是 Vue 框架,所以当前其渲染的 Root 节点为 Vue, 以此,我们视野可以暂时转移到 admin-base中的 Root.vue以及 RootWidget上, 其实现了整个 Vue 框架下的 Root 节点如何渲染,其中定义了多个 widget,比如登陆页,首页,忘记密码已经重置密码等页面, 在本文中我们着重关注渲染首页的能力,RootWidget将 DefaultMetadataMainViewWidget作为渲染 Props中的 page即首页提供给下层组件使用, 渐入佳境 DefaultMetadataMainViewWidget从名称中可以看到,其为元数据主视图,主要做两件事,1:提供 Mask 的渲染2:提供元数据上下文初始化 该组件主要通过观察路由变化触发上面两个动作,当路由发生变化,该组件 reloadPage将被调用,reloadPage方法通过组装路由参数构成一个唯一 key 向后段查询当前路由所对应的渲染信息, 随后将获取到的信息进行处理,初始化,即 元数据上下文初始化,在初始化后,会将获取到的数据注入到 MetadataViewWidget中, Mask 的渲染 关于 Mask 的渲染,在获取到数据后,将生成 maskTemplate,并将其赋值, DefaultMetadataMainView.vue文件将渲染该模板,并渲染到页面中 数据的变更 当上面两件任务完成后,将开始主视图的渲染,上文提到,DefaultMetadataMainViewWidget只负责 mask 的渲染和上下文的初始化,所以 DefaultMetadataMainViewWidget通过触发事件的方式来实现主视图的渲染, DefaultMetadataMainViewWidget将必要信息作为事件参数触发,MultiTabsContainerWidget接收到 reloadMainViewCallChaining事件后,开启主视图渲染, MultiTabsContainerWidget会刷新运行时上下文,即 refreshRuntimeContext,该方法将尝试查询并通过 createOrUpdateEnterTab方法创建 Tab 页,createOrUpdateEnterTab最终生成一个 MultiTabItem格式的对象,该对象描述了 Tab 的相关信息,随后调用 createTabContainerWidget创建 tab 的容器即新建了一个 MultiTabContainerWidget组件即单个 tab 的容器,随后调用 setActiveTabItem, 并获取其绑定的 Vue 组件,并将其组件放置在 KeepAlive内部,触发更新, 主视图的渲染 MultiTabContainerWidget继承自MetadataViewWidget,当 MetadataViewWidget数据发生变更, 其绑定的 Vue 组件将解析 viewTemplate, 获取到与该模板 dslNodeType想匹配的 Vue 组件,当前例子中为 View.vue,随后 View.vue开始渲染,View.vue文件只是一个纯粹的容器,当 View.vue被挂载时,其内部的 template属性包含了整个页面的描述信息,View.vue需要做的就是将这个 template翻译并渲染成 DOM 展现在浏览器上, 渲染整个页面 当 View.vue被挂载时,其内部的 template属性包含了整个页面的描述信息,View.vue主要做了两个事情,一:将 template 中的 widget转换为组件,二:根据当前的 template信息生成 slot信息, const currentSlots = computed<Slots | undefined>( () => DslRender.fetchVNodeSlots(props.dslDefinition) || (Object.keys(context.slots).length ? context.slots : undefined) ); const renderWidget = createCustomWidget(InternalWidget.View, { …context.attrs, type: props.type || viewType.value, template: props.dslDefinition, metadataHandle: props.metadataHandle || metadataHandle.value, rootHandle: props.rootHandle || rootHandle.value, parentHandle: props.parentHandle || parentHandle.value, slotName: props.slotName, inline: inlineProp } as ViewWidgetProps); 生成这两部分信息后,View.vue会将这两部分挂载到页面上,这两部分从代码中可以看出,主要靠 fetchVNodeSlots,createCustomWidget两个函数, export function createCustomWidget( widget: string, props: CustomWidgetProps ): RenderWidget | undefined public static fetchVNodeSlots(dsl: DslDefinition | undefined, supportedSlotNames?: string[]):…

    2025年3月19日
    80100
  • 如何提高自定义组件的开发效率

    引言 本文将通过前端的开发者模式带领大家提高自定义组件的开发效率 支持2024年9月6日之后用npm i安装的4.7.x之后的所有版本 介绍前端开发者模式 开发者模式的特性 浏览器控制台可以看到更多利于开发的日志输出 页面顶部状态栏消息模块的轮询接口,将只在页面刷新后请求一次,这样会减少开发阶段不必要的请求,以及解决后端断点调试的时候被消息轮询干扰的问题 页面视图的数据将不在走缓存,而是每次实时从base_view表里查询template字段获取,方便需要实时看通过xml修改的页面效果 如何进入开发者模式 通过在浏览器地址栏后追加;mode=dev刷新页面进入开发者模式,页面加载后可以在浏览器开发者工具的应用标签下的本地存储空间(即localStorage)中看到本标识的存储,如果想退出开发者模式可以手动清除该值 开发者模式的应用场景 1.通过控制台跳转到视图动作(ViewAction)的调试页面 页面刷新后,可以在浏览器开发者工具的控制台看到如下图的日志输出,直接点击该链接可以跳转到当前页面的调试链接弹窗视图动作、抽屉视图动作等以弹出层为展示效果的页面,之前的版本是无法进入调试链接查看的,现在可以在弹窗等视图动作点击后在控制台看到该链接点击进入调试页面 2.查看页面母版(mask)、布局(layout)的匹配情况 母版(mask)匹配结果布局(layout)匹配结果 3.查看视图组件(View)、字段组件(Field)、动作组件(Action)的匹配情况 通过浏览器开发者工具的控制台,我们可以看到每个视图、字段、字段匹配到的组件的class类名,这样我们就知道当前用的是那个组件,在自定义的时候可以在源码查看该组件类的实现代码,然后再选择是否继承该父类。另外我们在给组件定义SPI条件的时候,可以参考匹配入参和匹配结果内的属性。 匹配入参是当前元数据SPI的最全量注册条件 匹配结果是当前匹配到的组件的注册条件,一般情况下我们只需要在匹配结果的条件加上当前模型编码(model)、视图名称(viewName)、字段名称(name)、动作名称(actionName)等条件就可以完成自定义组件的覆盖。 在浏览器开发者工具的控制台,通过模型编码、视图名称、字段名称、动作名称等关键字快速搜索定位到需要查找的组件 控制台搜索快捷键:win系统通过ctrl+f,mac系统通过cmd+f 总结 在确保自定义部分代码最终正确被import导入到启动工程main.ts内的情况下,可以通过开发者模式在浏览器控制台打印的日志来排查组件未正确覆盖的问题。

    2024年9月6日
    2.0K00
  • 表格页自定义按钮如何获取搜索区域的查询条件

    介绍 在使用 Oinone 平台开发过程中,开发者可能会遇到自定义动作需要获取搜索条件并传递给后端的情况。本文将介绍如何利用 Oinone平台 实现此功能。 技术基础知识 当我们在自定义一个动作的时候要先明确自定义的动作类型是什么样的,在Oinone平台中,分为了如下几个动作: 1: 视图动作2: 服务端动作3: 客户端动作3: URL动作 功能步骤或代码示例 案例1、服务端动作,动作点击时候要拿到搜索内容,然后传递给后端。 import { ActionType, ActionWidget, SPI, ServerActionWidget } from '@kunlun/dependencies'; @SPI.ClassFactory( ActionWidget.Token({ name: 'name', model: 'model', actionType: ActionType.Server }) ) export class MyServerActionWidget extends ServerActionWidget { protected async clickAction() { const rst = this.getSearchRsqlAndQueryParams(); } } 案例2、视图动作点击的时候把搜索内容带到另外一个视图或者弹窗 import { ActionType, ActionWidget, SPI, ServerActionWidget } from '@kunlun/dependencies'; @SPI.ClassFactory( ActionWidget.Token({ name: 'name', model: 'model' }) ) export class MyDialogViewActionWidget extends DialogViewActionWidget { // 继承当前动作原本的class protected async clickAction() { const { queryData } = this.getSearchRsqlAndQueryParams(); this.action.context = queryData super.clickAction() return true } } 在上述代码中,我们自定义了一个服务器动作,并在点击触发函数中调用了getSearchRsqlAndQueryParams方法,该方法会返回一个对象: { rsql: String, // 搜索内容对应的rsql queryData: Object, // 搜索的数据 condition: Condition, // 搜索内容对应的数据结构 queryDataToString: Function // 将搜索内容转成JSON字符串 } 这样我们就可以根据业务场景使用对应的值。 注意事项 1: 确保正确导入所需的依赖包。2: 理解并适当修改代码以满足特定业务需求。 总结 本文介绍了在 Oinone 平台中如何自定义一个服务端动作,并获取搜索条件传递给后端的方法。通过合理利用这些功能,开发者可以更灵活地定制应用程序,满足不同的业务需求。 实践案例 如何自定义点击导出动作绑定指定模板

    2024年3月6日
    1.5K00
  • 如何增加页面消息通知轮询的间隔或者关闭轮询

    场景 oinone的前端页面默认自带了消息通知功能,在顶部状态栏可以看到消息的查看入口,默认每隔5秒查询一次最新的消息,我们可以通过自定义消息组件增加该间隔或者是关闭轮询 示例代码 修改轮询间隔 import { MaskWidget, NotificationWidget, SPI } from '@kunlun/dependencies'; @SPI.ClassFactory(MaskWidget.Token({ widget: 'notification' })) export class DemoNotificationWidget extends NotificationWidget { /** * 轮询间隔时间,单位: 秒 * @protected */ protected msgDelay = 30000; } 关闭轮询 import { MaskWidget, NotificationWidget, SPI } from '@kunlun/dependencies'; @SPI.ClassFactory(MaskWidget.Token({ widget: 'notification' })) export class DemoNotificationWidget extends NotificationWidget { protected mounted() { super.mounted(); // 清除轮询的定时器 this.msgTimer && clearInterval(this.msgTimer); // 挂载后手动查询一次消息 this.getMsgTotal(); } }

    2024年8月20日
    1.6K00
  • oio-input 输入框

    代码演示 <oio-input v-model:value="value"></oio-input> API Input 参数 说明 类型 默认值 版本 addonAfter 带标签的 input,设置后置标签 string|slot addonBefore 带标签的 input,设置前置标签 string|slot allowClear 可以点击清除图标删除内容 boolean defaultValue 输入框默认内容 string disabled 是否禁用状态,默认为 false boolean false maxlength 最大长度 number prefix 带有前缀图标的 input slot showCount 是否展示字数 boolean false suffix 带有后缀图标的 input slot type 声明 input 类型,同原生 input 标签的 type 属性,见:MDN(请直接使用 <a-textarea /> 代替 type="textarea")。 string text value(v-model:value) 输入框内容 string Input 事件 事件名称 说明 回调参数 update:value 输入框内容变化时的回调 function(e) pressEnter 按下回车的回调 function(e) Input.Search 代码演示 <oio-input-search v-model:value="value"></oio-input-search> Input.Search 事件 事件名称 说明 回调参数 search 点击搜索或按下回车键时的回调 function(value, event) 其余属性和 Input 一致。

    2023年12月18日
    2.5K00

Leave a Reply

Please Login to Comment