OpenDataV低代码平台新增组件流程
OpenDataV计划采用子库的方式添加子组件,即每一个组件都当做一个子库,子库有自己的依赖,而项目本身的依赖只针对框架,因此每一个组件我们都当做一个子库来开发。下面我带着大家一步步详细的开发一个数字展示组件。
创建组件目录和文件
- 进入组件库目录下
所有的可拖拽组件都存放在src/resource/components
目录下
cd src/resource/components
- 根据组件名称创建目录
默认组件目录是以组件的名称命名,当然也可以根据自己的要求命名,组件可以放在components
目录下,也可以放在其子目录的目录下。
mkdir DigitalText
- 创建组件所需的固定文件
每个组件必须的文件有vue文件xxx.vue
、配置文件config.ts
、导出文件index.ts
,每个文件有自己的用处,vue文件不用说了是组件渲染的主体,导出文件名称固定为index.ts
,主要是导出组件的信息给外部引用,配置文件主要是在编辑页面右侧展示的配置项,这个我们后面再详述。所以这里我们需要创建三个文件:DigitalText.vue、config.ts、index.ts
以上我们就创建好了组件所需的文件,下面就需要做组件的初始化了
初始化组件文件
因为我们的组件都是以子库的方式引入,所以需要进行包的初始化,执行以下命令
cd src/resource/components/Text/DigitalText
npm init
这里使用npm
初始化包会让我们选择填写部分数据。
下面我们先初始化一下组件文件DigitalText.vue
,先初始化最简单的组件数据
<template>
<div>数字展示</div>
</template>
<script lang="ts" setup></script>
<style lang="less" scoped></style>
然后我们要初始化组件的配置文件config.ts
import { ComponentGroup, FormType } from '@/enum'
import type { PropsType } from '@/types/component'
import { BaseComponent } from '@/resource/models'
export const componentName = 'Digital'
class DigitalComponent extends BaseComponent {
constructor(id?: string, name?: string, icon?: string) {
super({
component: componentName,
group: ComponentGroup.TEXT,
name: name ? name : '数字文本',
id,
width: 100,
height: 30,
icon
})
}
}
export default DigitalComponent
这里要说明的点:componentName
是组件在项目中的注册名称,因此必须保证唯一,group
是给组件分组,这里的分组主要是展示在组件拖拽页面,其类型的ComponentGroup
是固定好的,可以自己增加,展示位置如下:
name
是组件在拖拽页面上显示的名称,width
和height
是组件拖拽到画布上显示的初始大小
配置完组件后数据后,就可以配置导出文件index.ts
了,主要是导出组件名、组件对象和配置项。
import DigitalTextComponent, { componentName } from './config'
export default {
componentName,
component: () => import('./DigitalText.vue'),
config: DigitalTextComponent
}
初始化到这一步,我们的组件已经可以在编辑页面正常使用了,看一下效果:
在右边的编辑页面我们看到有样式
和属性
,所有的组件都包含基础样式位置大小
,包括组件的上下边距和宽高,属性包含公共属性,其中组件
和组件ID
无法修改,主要是展示来看的,名称
可以修改,名称属性主要是展示在图层上,修改名称后图层上会响应的显示修改后的名称。
这是最基础的组件,只能展示固定数据,不能进行任何配置,下面我们要做组件的配置项。
组件配置项
样式配置
作为文字显示组件,最基础的字体相关属性配置应该要有,比如字体、字体颜色、字体大小、字体宽度
,配置项依然是在配置文件中添加,继承自基础组件类的私有属性_style
class DigitalTextComponent extends BaseComponent {
constructor(id?: string, name?: string, icon?: string) {......}
_style: PropsType[] = [
{
label: '字体设置',
prop: 'font',
children: [
{
prop: 'color',
label: '颜色',
type: FormType.COLOR,
componentOptions: {
defaultValue: 'skyblue'
}
},
{
prop: 'fontSize',
label: '字体大小',
type: FormType.NUMBER,
componentOptions: {
defaultValue: 20
}
},
{
prop: 'fontWeight',
label: '字体宽度',
type: FormType.FONT_WEIGHT,
componentOptions: {
defaultValue: 200
}
},
{
prop: 'fontFamily',
label: '字体',
type: FormType.FONT_STYLE,
componentOptions: {
defaultValue: 'Arial'
}
}
]
}
]
}
样式配置的格式已经定义好了,其中需要注意的是所有children
下的子项中prop
必须是html
元素的css
属性,具体的css
属性名称并不是我们在style
文件中填写的,而是在js
中对应的名称,这个可以在网上搜索:css3 中文手册
,类似如下:
我们再详述一下各配置项的意义:
- label:配置显示的分组名
- prop:唯一的属性区分,此属性要与同级别中的其他配置不同
- children:此属性组下面的配置项
- label:每个属性的名称
- prop:
css
属性值 - type:属性编辑时显示的组件类型,目前可显示的组件是固定的,类型都定义在
FormType
中 - componentOptions:属性对应的配置项,不同类型的组件有不同的配置项,具体可以在
src/types/component.d.ts
中查看定义,所有配置都有defaultValue
配置,作为属性初始化时的默认值
配置完样式后,我们在编辑页面看一下效果:
搞清楚了样式的配置,下面我们再说说属性的配置,属性配置与样式配置格式一致,有一些小细节需要注意。
属性配置
属性配置是继承私有变量_prop
,配置格式与样式相同,我们这里配置一个示例属性:
class DigitalTextComponent extends BaseComponent {
constructor(id?: string, name?: string, icon?: string) {......}
_prop: PropsType[] = [
{
label: '数据配置',
prop: 'dataconfig',
children: [
{
prop: 'data',
label: '数据',
type: FormType.NUMBER,
componentOptions: {
defaultValue: 100000,
max: 99999999,
min: 0
}
}
]
}
]
}
格式这里就不解释了,这里我们用到了数值类型,因此可以配置最大最小值。
接下来就是要在vue
文件中使用属性配置了,属性不像样式,样式是html
元素本身就支持的,因此只要我们配置好,就可以生效了,但是属性是组件专有的,什么属性要产生什么效果全凭我们自己书写逻辑,因此配置好属性我们只会在编辑页面看到属性展示和配置,但是实际配置后是没有任何效果的,具体效果我们在vue
中实现。
属性使用
首先我们要添加一个类型定义文件,因为ts
最基础的优势就是类型提示,而我们封装的组件基类是通用的,因此需要在每个组件中使用自己的属性类型定义,定义如下:
// DigitalText/type.ts
export interface DigitalType {
dataconfig: {
data: number
}
}
为了准确的进行提示,类型定义必须和属性配置一直,具体来讲就是children
下面的prop
作为属性值,children
外面的prop
作为属性键,可以对比一下type.ts
中的配置和_prop
的配置。
组件的配置信息是通过外部传入的,所以所有组件都必须接收外部数据,我们已经定义好了固定的格式
const props = defineProps<{
component: DigitalTextComponent
}>()
组件相关的所有信息都将通过component
传入进来,为了监听属性变化和类型提示,我们封装了一个hook,减少每个组件中通用的处理,useProp
的使用如下:
const propChange = (prop: string, key: string, value: number) => {
console.log(prop, key, value)
}
const { propValue } = useProp<DigitalType>(props.component, propChange)
useProp
接收三个参数,一个是component
,主要是为了添加类型提示,所以这里也传入了一个泛型定义,就是我们在type.ts
中定义的类型,另外两个参数是属性变化回调函数和样式变化回调函数。一般情况下我们只需要处理属性变化回调,样式变化是自动生效的,所以基本上不用处理,如果有特殊需求才需要。属性变化回调函数中有三个参数,prop
对应的是属性配置中外层的prop
值,key
对应的是属性配置中children
中的prop
值,而value
就是属性变化的值。
最终我们的属性处理结果如下:
<template>
<div>{{ data }}</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import DigitalTextComponent from './config'
import { useProp } from '@/resource/hooks'
import { DigitalType } from './type'
const props = defineProps<{
component: DigitalTextComponent
}>()
const propChange = (prop: string, key: string, value: number) => {
if (prop === 'dataconfig' && key === 'data') {
data.value = value
}
}
const { propValue } = useProp<DigitalType>(props.component, propChange)
const data = ref<number>(propValue.dataconfig.data)
</script>
<style lang="less" scoped></style>
看一下页面上的效果:
上面我们用了属性回调去处理值变化响应,实际上还有其他的方式可以处理,我们要明白属性回调的根本需求是什么?主要就是为了编辑了对应的属性后,我们在组件内能监测到变化反馈到显示上。相同这一点,可用的方法就多了。
- 直接使用
props
传递的属性值在template
中渲染数据
<template>
<div>{{ propValue.dataconfig.data }}</div>
</template>
<script lang="ts" setup>
import DigitalTextComponent from './config'
import { useProp } from '@/resource/hooks'
import { DigitalType } from './type'
const props = defineProps<{
component: DigitalTextComponent
}>()
const { propValue } = useProp<DigitalType>(props.component)
因为vue
响应式的原因,props
中的数据是可以响应变化的,那么我们直接在template
中使用即可,不需要做任何监测。
- 使用
computed
或者watch
监听属性变化
这里和上面是一样的道理,vue
会自动帮我们处理响应式数据,只要用vue
的计算属性或者watch
也可以监听到属性变化。
<template>
<div>{{ data }}</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
import DigitalTextComponent from './config'
import { useProp } from '@/resource/hooks'
import { DigitalType } from './type'
const props = defineProps<{
component: DigitalTextComponent
}>()
const { propValue } = useProp<DigitalType>(props.component)
const data = computed<number>(() => {
return propValue.dataconfig.data
})
</script>
<style lang="less" scoped></style>
- 属性变化回调的另一种用法
<template>
<div>{{ data }}</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import DigitalTextComponent from './config'
import { useProp } from '@/resource/hooks'
import { DigitalType } from './type'
const props = defineProps<{
component: DigitalTextComponent
}>()
const propChange = () => {
data.value = propValue.dataconfig.data
}
const { propValue } = useProp<DigitalType>(props.component, propChange)
const data = ref<number>(propValue.dataconfig.data)
</script>
<style lang="less" scoped></style>
属性变化回调接收任何参数,我们可以选择接收参数,也可以不接收参数,在一些配置项比较多的组件中,我们不想在属性回调中去一个一个判断变化的属性,那么就可以使用这种方式,在这种方式中我们只是把属性回调作为一个通知,即通知我们属性发生变化了,而我们不关心哪一个属性发生了变化,把所有的属性都修改一遍即可,虽然听起来比较麻烦,但是在一些复杂组件中确实很有作用。在这里我们要明白,只要属性发生了变化,那么prop
中的数据也必定发生了变化,所以我们随时取prop
中的数据它都是最新的。
总结
到这里,一个组件的整个添加过程就讲完了,根据目前的开发进度来看,基本上所有的部分都讲到了,如果有人在使用过程中发现了什么问题或者有哪些地方不够清楚的,可以在项目的issue中提,也可以通过其他方式反馈。
添加微信公众号了解更多信息:
OpenDataV低代码平台新增组件流程的更多相关文章
- OpenDataV低代码平台增加自定义属性编辑
上一篇我们讲到了怎么在OpenDataV中添加自己的组件,为了让大家更快的上手我们的平台,这一次针对自定义属性编辑,我们再来加一篇说明.我们先来看一下OpenDataV中的属性编辑功能. 当我们拖动一 ...
- 低代码平台--基于surging开发微服务编排流程引擎构思
前言 微服务对于各位并不陌生,在互联网浪潮下不是在学习微服务的路上,就是在使用改造的路上,每个人对于微服务都有自己理解,有用k8s 就说自己是微服务,有用一些第三方框架spring cloud, du ...
- 分析师机构发布中国低代码平台现状分析报告,华为云AppCube为数字化转型加码
摘要:Forrester指出,中国企业数字化转型过程中,有58%的决策者正在采用低代码工具进行软件构建,另有16%的决策者计划采用低代码. 华为消息,知名研究与分析机构Forrester Resear ...
- 基于低代码平台(Low Code Platform)开发中小企业信息化项目
前言:中小企业信息化需求强烈,对于开发中小企业信息化项目的软件工作和程序员来说,如何根据中小企业的特点,快速理解其信息化项目的需求并及时交付项目,是一个值得关注和研讨的话题. 最近几年来,随着全球经济 ...
- 干货!可以使用低代码平台代替Excel吗?
低代码开发平台可以代替Excel?不用惊讶,答案是肯定的,而且,低代码开发平台可以完全代替Excel.例如Zoho Creator低代码平台,可以围绕数据存储.管理和创建工作流程.期间不需要IT人员介 ...
- 2021年哪个低代码平台更值得关注?T媒体盘点国内主流低代码厂商
2020年圣诞前夜,国内知名创投科技媒体T媒体旗下的T研究发布了2020中国低代码平台指数测评报告.报告除了对国内低代码行业现状进行总结外,还对主流低代码厂商的市场渗透和曝光进行测评. 报告认为,低代 ...
- 使用WtmPlus低代码平台提高生产力
低代码平台的概念很火爆,产品也是鱼龙混杂. 对于开发人员来说,在使用绝大部分低代码平台的时候都会遇到一个致命的问题:我在上面做的项目无法得到源码,完全黑盒.一旦我的需求平台满足不了,那就是无解. ...
- 开源低代码平台开发实践二:从 0 构建一个基于 ER 图的低代码后端
前后端分离了! 第一次知道这个事情的时候,内心是困惑的. 前端都出去搞 SPA,SEO 们同意吗? 后来,SSR 来了. 他说:"SEO 们同意了!" 任何人的反对,都没用了,时代 ...
- 低代码BPM平台
为了做出明智的决策并为客户提供服务,员工需要在正确的环境中使用正确的工具和访问关键信息的权限.但是,当业务关键信息分散在多个现成的和自定义编码的应用程序中时,员工效率会降低,客户体验也会受到影响. 低 ...
随机推荐
- NC14662 小咪买东西
NC14662 小咪买东西 题目 题目描述 小咪是一个土豪手办狂魔,这次他去了一家店,发现了好多好多( \(n\) 个)手办,但他是一个很怪的人,每次只想买 \(k\) 个手办,而且他要让他花的每一分 ...
- golang的超时处理使用技巧
原文链接:https://www.zhoubotong.site/post/57.html golang的超时处理 2天前Go实例技巧25 大家知道Select 是 Go 中的一个控制结构,每个 ...
- ReentrantLock 公平锁源码 第1篇
ReentrantLock 1 这篇还是接着ReentrantLock的公平锁,没看过第0篇的可以先去看上一篇https://www.cnblogs.com/sunankang/p/16456342. ...
- esp8266模拟输入(ADC)检测问题
今天使用esp12f读取A0数据时一直出现错误; Serial.println(analogRead(A0));读取值一直为1024 因为前段时间一直用的是开发板,读取电压值正常 而从昨天换为了esp ...
- zabbix监控添加学习笔记
在实际生产环境中,除了CPU.内存等一些系统信息可以挂载zabbix的自带模板Template OS Linux:但是一些公司开发的定制服务需要自己写模板或者监控项去监控: 一.监控公司的java服务 ...
- python获取线程返回值
python获取线程返回值 前言 工作中的需求 将前端传过来的字符串信息通过算法转换成语音,并将语音文件返回回去 由于算法不是我写的,只需要调用即可,但是算法执行速度相当缓慢 我的优化思路是,将前端的 ...
- SpringBoot定时任务 - 什么是ElasticJob?如何集成ElasticJob实现分布式任务调度?
前文展示quartz实现基于数据库的分布式任务管理和job生命周期的控制,那在分布式场景下如何解决弹性调度.资源管控.以及作业治理等呢?针对这些功能前当当团队开发了ElasticJob,2020 年 ...
- Odoo 如何下载指定版本源码 && .cfg配置参数
# 我们使用应用市场上的模块的时候,经常会碰到模块只兼容特定版本,要将模块兼容到自己版本来的时候,就需要下载它原兼容odoo的版本运行. # 这里的-b后面加的11.0就是它的版本.在git中也就是分 ...
- 内存问题难定位,那是因为你没用ASAN
摘要:ASAN全称:Address Sanitizer,google发明的一种内存地址错误检查器.目前已经被集成到各大编译器中. 本文分享自华为云社区<内存定位利器-ASAN使用小结>,作 ...
- python的嵌入式开发
今天晚上注定我要玩一夜这个东西,太爽了,给力! 烧写固件成功, http://blog.csdn.net/Lingdongtianxia/article/details/78248888 要点总结:如 ...