yc-config-create-setting
TypeScript icon, indicating that this package has built-in type declarations

1.32.2 • Public • Published

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 共接收三个参数: VueMapping options

参数一 Vue

介绍

该参数很简单,就是Vue3,使用 import * as Vue from 'vue' 就可以拿到。其实原本在设计的时候是不用传入 Vue3 ,但是近几年来 vue 也在持续的更新迭代,为了后期能够更好的去介入以及兼容未来高版本的Vue,所以才把 Vue3 进行单独拎出来作为参数进行处理。

参数二 Mapping

介绍

Mapping 参数它主要的作用就是告知 yc-config-create-settingVue 中,组件配置信息的映射关系。它主要包含的映射关系含有:组件名称、组件数据双向绑定的 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

Readme

Keywords

none

Package Sidebar

Install

npm i yc-config-create-setting

Weekly Downloads

92

Version

1.32.2

License

ISC

Unpacked Size

99.7 kB

Total Files

6

Last publish

Collaborators

  • clover2