yc-config-create-setting
v1.32.4
Published
Downloads
79
Readme
yc-config-create-setting
介绍
yc-config-create-setting
起源于低代码设计研发。为了方便对节点的操作,以及方便数据库存储。
它是一个基于 Vue3
& Typescript
进行实现的全新编程方式 - (函数配置化编程
)。它所带来的就是能够让你以函数式的方式进行编程。在 Typescript
的加持下,有着良好的配置项推导能力,同时也去除掉了 HTML
标签的编写。也方便了快速进行定位排除问题。
它和传统的 Vue
代码编写的区别就是在于,Setting
它是完全采用了脚本的方式进行编写,也类似于 Vue3
的组合式API。它以最简单最明了的方法进行实现组件信息。让其每一个节点都能够有独立自主的能力,并且让每一个节点都能够实现 export
,有效的省去了重复性的代码,在设计的时候也逐步遵循着 低耦合高内聚
。
优点
1、支持配置化开发项目。
2、实体节点独立控制,让每一个组件节点只负责根据数据信息去处理自身的效果。
3、支持二次封装,支持多种UI框架,以及自定义的组件和自定义方法输出,使用它更加贴合你的项目。
4、减少HTML标签,让文件中表单代码更加简洁,事务节点追踪更加的简单清晰。
5、支持 Typescript
有着良好的推导能力,支持自定义组件 Typescript
的处理。
6、可支撑配置信息进行数据库存储。充分发挥处理节点的作用域能力。
7、整合组件资源信息,统一进行管理。开发者只需要处理好Setting
的搭建信息即可。
案例
插件:yc-setting-element-plus
安装使用
npm方式
npm install yc-config-create-setting
创建环境
import * as Vue from 'vue';
import { ElInput } from 'element-plus'
const mapping = const ElSettingMapping = {
// 组件映射配置
COMPONENT_MAPPING: {
ElInput,
},
// 组件数据双向绑定的 prop 名称
MODEL_NAME_MAPPING: {
modelValue: ['ElInput'],
},
// 组件数据双向绑定更新的对应事件信息
EMIT_NAME_MAPPING: {
'update:modelValue': ['ElInput']
},
};
const $Setting = YcConfigCreateSetting(Vue, mapping, { autoMappingComponent: true });
// 开始搭建环境
const { UI, Generate } = $Setting('App', { text: 'WelCome Use Entity' );
// 创建节点信息
const WelComeText = UI('div').setContent(vm => vm.text);
// 获取组件信息
const { Component } = Generate(WelComeText);
// 导出组件信息
export default Component
参数配置
yc-config-create-setting
共接收三个参数: Vue
、 Mapping
、 options
。
参数一 Vue
介绍
该参数很简单,就是Vue3
,使用 import * as Vue from 'vue'
就可以拿到。其实原本在设计的时候是不用传入 Vue3
,但是近几年来 vue
也在持续的更新迭代,为了后期能够更好的去介入以及兼容未来高版本的Vue
,所以才把 Vue3
进行单独拎出来作为参数进行处理。
参数二 Mapping
介绍
Mapping
参数它主要的作用就是告知 yc-config-create-setting
在 Vue
中,组件配置信息的映射关系。它主要包含的映射关系含有:组件名称、组件数据双向绑定的 prop 名称、组件数据双向绑定更新的对应事件信息。
Typescript
export interface Mapping {
// 组件映射配置
COMPONENT_MAPPING?: Record<string, unknown>;
// 组件数据双向绑定的 prop 名称
EMIT_NAME_MAPPING?: Record<string, string[]>;
// 组件数据双向绑定更新的对应事件信息
MODEL_NAME_MAPPING?: Record<string, string[]>;
// 组件双向绑定的时候,默认的初始值信息
DEFAULT_VALUE_MAPPING?: Record<string, unknown>;
// 组件数据必填的校验信息
DEFAULT_REQUIRED_RULE_MAPPING?: Record<string, (config: Record<string, unknown>, message: string | string[]) => Array<{
required?: boolean;
message?: string;
trigger: string;
}>>;
}
配置案例
// element-plus,这里采用的是组件名称,自动去全局注册信息里面查找的配置方式
const ComponentNames = [ 'ElButton', 'ElInput', 'ElInputNumber', 'ElRadio', 'ElPopover', 'ElTooltip','ElPagination' ] as const;
// 创建组件映射关系对象
const COMPONENT_MAPPING = ComponentNames.reduce(
(obj, key: ComponentNameType) => {
obj[key] = key;
return obj;
},
{} as Record<ComponentNameType, ComponentNameType>
);
const ElSettingMapping = {
// 组件映射配置
COMPONENT_MAPPING,
// 组件数据双向绑定的 prop 名称
MODEL_NAME_MAPPING: {
modelValue: ['ElInput', 'ElInputNumber', 'ElRadio'],
checked: ['ElCheckTag'],
visible: ['ElPopover', 'ElTooltip'],
pageSize: ['ElPagination'],
currentPage: ['ElPagination'],
},
// 组件数据双向绑定更新的对应事件信息
EMIT_NAME_MAPPING: {
'update:modelValue': ['ElInput','ElInputNumber', 'ElRadio'],
'update:checked': ['ElCheckTag'],
'update:visible': ['ElPopover', 'ElTooltip'],
'update:pageSize': ['ElPagination'],
'update:currentPage': ['ElPagination'],
},
};
export default ElSettingMapping;
参数三 Options
介绍
它是一个选项配置信息,它主要所需要发挥的作用就是,便于后期未来的扩展处理。目前它只有两个配置项字段。
Typescript
export interface Options {
// 是否自动映射,它的作用就是,当你配置的 `COMPONENT_MAPPING` 中没有找到对应的组件信息的时候,就会自动去全局组件注册的信息对象里面去查找匹配。
autoMappingComponent?: boolean;
// 拦截器配置,它目前也只是做了个组件信息拦截的处理。
interceptMapping?: {
// 它的作用就是能够让你优先拿到【组件名称】去处理拦截处理,也就是它能有更高的对组件映射关系的控制权限
component?: (name: string) => string | Vue.Component;
};
}
配置案例
const ComopnentMapping: Record<string, string> = {
box: 'div',
}
const options = {
autoMappingComponent: true,
interceptMapping: {
component: (name) => {
if (name in ComopnentMapping) {
return ComopnentMapping[name]
}
return name
}
}
}
export default options;
实体方法
介绍
在 yc-config-create-setting
中会把为一个组件配置的信息作为一个节点,为了能够更好的去管理这些节点信息。yc-config-create-setting
提供了一个 UI
的方法,该方法就是用来管理组件的配置项信息。它最大的作用就是不仅能够以链式调用的方式去配置,还可以进行去调用你配置信息。例如:当你的组件渲染完毕以后,它就可以快速直接去使用组件节点信息。
// 利用已经封装好的element-plus进行快速搭建
import BuildElSetting from "@/yc-setting-element-plus";
// 获取环境信息
const ElSetting = BuildElSetting();
// 开始搭建环境,并获取element-plus的组件工具 El 和 生成组件的方法 Generate
const { El, Generate } = ElSetting('App');
// 创建一个案例实体
const button = El.Button({ type: 'primary' }).setContent('按钮').on('click', (_vm: any, name: string) => {
return `[click]: ${name}, Welcome Use Entity.`
});
// 生成组件信息,以及 mounted 钩子
const { Component, mounted } = Generate(button);
// 添加钩子信息
mounted(() => {
const result = button.trigger('click','戴向天') as string;
console.log('result=>',result)
})
// 导出组件信息
export default Component
setType
设置当前组件信息
entity.setType(type: IEntity.Type<S>): Entity;
// 使用方法
entity.setType('div');
setModel
设置数据双向绑定的字段信息
entity.setModel(model: IEntity.String<S>): Entity;
// 使用方法
entity.setModel('userName') // 字符串
.setModel((vm)=> 'userName'); // 通过函数进行返回字符串
setProps
设置组件的 props
信息。
entity.setProps<P extends U['props']>(props: ((vm: T) => P) | P): Entity;
// 使用方法
entity.setProps({ type: 'primary' }) // 直接传入 props
.setProps((vm)=>{ // 通过函数动态传入 props
return {
type: 'primary'
}
})
addProps
累加组件的 props
信息。
entity.addProps<P extends U['props']>(props: ((vm: T) => P) | P): Entity;
// 使用方法
entity.addProps({ type: 'primary' }) // 直接传入 props
.addProps((vm)=>{ // 通过函数动态传入 props
return {
disabled: true
}
})
setClass
设置 class
样式名称
entity.setClass(_class: IEntity.ClassName<S>): Entity;
// 使用方法
entity.setClass('item') // 字符串
.setClass((vm) => 'item') // 函数返回
.setClass(['item', (vm)=> 'item1', { item2: true } ]) // 多种结构
addClass
添加 class
样式名称
entity.addClass(_class: IEntity.ClassName<S>): Entity;
// 使用方法
entity.addClass('item') // 字符串
.addClass((vm) => 'item') // 函数返回
.addClass(['item', (vm)=> 'item1', { item2: true } ]) // 多种结构
setStyle
entity.setStyle(_style: IEntity.Config<S>['style']): Entity;
// 使用方法
entity.setStyle('background: red;') // 字符串
.setStyle((vm) => 'background: red;') // 函数返回
.setStyle({background: 'red'}) // 多种结构
setContent
设置默认的插槽。同理与 Entity.setSlot('default','xxxx')
。
entity.setContent<Info extends IEntity.SlotInfo<S> = IEntity.SlotInfo<S>>(slotInfo: Info) :Entity;
// 使用方式
entity.setContent('WelCome Use Entity')
.setContent((vm,scoped)=>'WelCome Use Entity')
click
点击事件绑定。 同理 entity.on('click',()=>{})
click<
N extends 'click',
K extends EN = EN,
H = (N extends K ? E[N] extends ((...arg: any) => any) ? ((vm: T, ...agrs: Parameters<E[N]>) => ReturnType<E[N]>) : (vm: T, ...args: any) => any : (vm: T, ...args: any) => any),
>(handler: H, modifier?: IEntity.Modifier<S>): Entity;
// 使用方法
entity.click((vm,...args)=>{
console.log('【click】我被触发了')
})
input
点击事件绑定。 同理 entity.on('input',()=>{})
click<
N extends 'input',
K extends EN = EN,
H = (N extends K ? E[N] extends ((...arg: any) => any) ? ((vm: T, ...agrs: Parameters<E[N]>) => ReturnType<E[N]>) : (vm: T, ...args: any) => any : (vm: T, ...args: any) => any),
>(handler: H, modifier?: IEntity.Modifier<S>): Entity;
// 使用方法
entity.input((vm,...args)=>{
console.log('【input】我被触发了')
})
change
点击事件绑定。 同理 entity.on('change',()=>{})
click<
N extends 'change',
K extends EN = EN,
H = (N extends K ? E[N] extends ((...arg: any) => any) ? ((vm: T, ...agrs: Parameters<E[N]>) => ReturnType<E[N]>) : (vm: T, ...args: any) => any : (vm: T, ...args: any) => any),
>(handler: H, modifier?: IEntity.Modifier<S>): Entity;
// 使用方法
entity.change((vm,...args)=>{
console.log('【change】我被触发了')
})
keydown
点击事件绑定。 同理 entity.on('keydown',()=>{})
click<
N extends 'keydown',
K extends EN = EN,
H = (N extends K ? E[N] extends ((...arg: any) => any) ? ((vm: T, ...agrs: Parameters<E[N]>) => ReturnType<E[N]>) : (vm: T, ...args: any) => any : (vm: T, ...args: any) => any),
>(handler: H, modifier?: IEntity.Modifier<S>): Entity;
// 使用方法
entity.click((vm,...args)=>{
console.log('【keydown】我被触发了')
})
trigger
触发自身配置的事件信息
entity.trigger<N extends string = string, K extends EN = EN>(eventName: N | K, ...args: unknown[]): unknow;
// 使用方式
entity.on('click',(vm,name)=>{
return `你好!${name}`
})
const result = entity.trigger('click','Entity'); // result=> 你好!Entity
triggerNode
触发组件内置函数
entity.triggerNode<R = undefined>(eventName: string, ...args: unknown[]): R;
// 使用方法
entity.triggerNode('change');
getVNode
在渲染成功后,可以通过该方法进行获取当前节点的信息 h
方法所生成的 vnode
信息。
entity.getVNode(): unknow | null;
getRefNode
在渲染成功后, 可以通过该方法进行获取组件实体信息。也就是返回 this.$ref[xxx]
。
entity.getRefNode(): unknow | null;
getValue
获取当前节点 model
数据信息。前提是需要进行绑定 model
字段信息。
entity.getValue<R = unknown>(): R;
setValue
设置当前节点 model
数据信息。前提是需要进行绑定 model
字段信息。
entity.setValue<T>(value: T): Entity;
// 使用方法
entity.setValue('Welcome Use Entity')
setAutoUpdate
是否在渲染成功后,再次进行修改 Entity 时进行强制组件重新渲染,从而让组件的视图更新。
entity.setAutoUpdate(isImmediatelyUpdate: boolean): Entity;
$forceUpdate
在渲染成功后,再次进行修改组件配置项信息的时候,若是视图没有得到更新,该方法可以进行强制性渲染更新视图。
entity.$forceUpdate(): Entity;
setKey
设置当前节点的唯一标识,等同于 :key="key"
。默认会自动生成。
entity.setKey(key: IEntity.String<S> | IEntity.Number<S>): Entity;
// 使用方法
entity.setKey('key') // 字符串
.setKey(1) // 数字
.setKey((vm) => 'key') // 通过函数返回字符串
.setKey((vm) => 1); // 通过函数返回数字
setFilter
设置
指定的配置项参数不做解析处理的字段信息。默认: ['type']
。
entity.setFilter<K extends keyof IEntity.Config<S> & string>(keys: K[]): Entity;
// 使用方法
entity.setFilter(['type'])
addFilter
添加
指定的配置项参数不做解析处理的字段信息。
entity.addFilter<K extends keyof IEntity.Config<S> & string>(key: K): Entity;
// 使用方法
entity.addFilter('type');
removeFilter
移除
指定的配置项参数不做解析处理的字段信息。
entity.removeFilter<K extends keyof IEntity.Config<S> & string>(key: K): Entity;
// 使用方法
entity.removeFilter('type');
del
删除指定的属性信息
entity.del<K extends keyof IEntity.Config<S>>(key: K): Enity;
// 使用方法
entity.del('props');
setConfig
设置配置项信息
enityt.setConfig(config: IEntity.ConfigWithoutType<S> = {}): Entity;
// 使用方法
entity.setConfig({ style: 'background: red' })
setKeyValue
可进行对指定的字段数据信息进行设置。获取添加自定义的字段信息。
entity.setKeyValue(key: string, value: unknown): Entity;
// 使用方法
entity.setKeyValue('customField','Entity')
.setKeyValue('type', 'span');
get
获取当前 Enityt
的配置项信息。
entity.get(): IEntity.Config
// 使用方法
const config = entity.get();
console.log('config=>', config);
copy
复制一个当前的 Entity
。并返回
entity.copy(): Entity
setAlias
设置当前Enityt
的别名。
entity.setAlias(alias: IEntity.String<S>): Entity;
// 使用方法
entity.setAlias('组件别名') // 字符串
.setAlias((vm)=> '组件别名'); // 通过函数进行返回字符串
setRef
设置组件ref
信息。默认自动生成
entity.setRef(ref: IEntity.String<S>): Entity;
// 使用方法
entity.setRef('entityRef') // 字符串
.setRef((vm)=> 'entityRef'); // 通过函数进行返回字符串
setIf
设置是否允许解析渲染。
entity.setIf(_if: IEntity.Boolean<S>): Entity;
// 使用方法
entity.setIf(false) // 布尔值
.setIf((vm) => false) // 函数返回布尔值
setSyncKeyValue
设置指定同步更新的字段信息
entity.setSyncKeyValue(key: string, value: IEntity.SyncType = key): Entity;
// 使用方法
entity.setSyncKeyValue('currentPage')
.setSyncKeyValue('currentPage', 'page')
.setSyncKeyValye('currentPage', {
key: 'page',
emit: 'current-change'
})
setSync
批量设置指定同步更新的字段信息
entity.setSync(sync: Record<string, IEntity.SyncType>): Entity;
// 使用方法
entity.setSyncKeyValue({
currentPage: 'page',
pageSize: {
key: 'size',
emit: 'sizeChange'
}
})
setDirective
设置指令信息
entity.setDirective(directive: IEntity.IDirective<S>): Entity;
// 使用方法
entity.setDirective({ name: 'show', value: vm => vm.show })
.setDirective({ name: vm => 'show', value: vm => vm.show })
setSlot
设置插槽信息
entity.setSlot(slotName: U['slots'] & string, slotInfo: IEntity.SlotInfo<S>): Entity;
// 使用方式
entity.setSlot('default','WelCome Use Entity') // 字符串
.setSlot('default',new Date().getTime()) // 数字
.setSlot('default',false) // 布尔
.setSlot('default',['WelCome Use Entity']) // 数组
.setSlot('default', entity.copy()) // Entity
.setSlot('default',(vm, scoped) => 'WelCome Use Entity') // 函数返回字符串
.setSlot('default',(vm, scoped) => ['WelCome Use Entity']) // 函数返回数组
.setSlot('default',(vm, scoped) => entity.copy()) // 函数返回 Entity
.setSlot('default',(vm, scoped) => [entity.copy()]) // 函数返回数组 Entity
setSlotMap
批量设置插槽信息
entity.setSlotMap(slotMap: IEntity.Config<S>['slots']): Entity;
// 使用方式
entity.setSlotMap({
default: 'Welcome Use Entity',
header: (vm)=> 'Welcome Use Entity',
})
.setSlotMap((_vm)=>{
return {
default: 'Welcome Use Entity',
header: (vm)=> 'Welcome Use Entity',
}
})
on
设置事件信息,通常是用于组件通过 $emit
进行暴露出来的方法
entity.on<
N extends string = string,
K extends EN = EN,
H = (N extends K ? E[N] extends ((...arg: any) => any) ? ((vm: T, ...agrs: Parameters<E[N]>) => ReturnType<E[N]>) : (vm: T, ...args: any) => any : (vm: T, ...args: any) => any),
>(
eventName: N | K | {
name: N | K,
handler?: H,
modifier?: IEntity.Modifier<S>,
event: boolean;
},
handler?: H,
modifier?: IEntity.Modifier<S>
): Entity
// 使用方法
entity.on('click',(vm,...args)=>{
console.log('【on】我被触发了')
})
setIntercept
设置自定义拦截器
entity.setIntercept(intercept: IEntity.Config<S>['intercept']): Entity;
// 使用方式
entity.setIntercept({
before(configEntity, vm){
return configEntity
},
after(analysisEntity, vm){
return analysisEntity
}
})
开发解答
Author:戴向天
QQGroup:602504799
Date: 2023-12-26