com um clique
add-screen-component
// 在摸鱼低代码自助大屏中新增自定义组件,包括创建组件 Vue 文件、数据定义文件、配置面板文件,并在 ComUtils.ts 中注册枚举、在 index.ts 中注册导出。当用户提到"大屏新增组件"、"自助大屏添加组件"、"screen 新增组件"、"添加大屏自定义组件"时使用此 skill。
// 在摸鱼低代码自助大屏中新增自定义组件,包括创建组件 Vue 文件、数据定义文件、配置面板文件,并在 ComUtils.ts 中注册枚举、在 index.ts 中注册导出。当用户提到"大屏新增组件"、"自助大屏添加组件"、"screen 新增组件"、"添加大屏自定义组件"时使用此 skill。
| name | add-screen-component |
| description | 在摸鱼低代码自助大屏中新增自定义组件,包括创建组件 Vue 文件、数据定义文件、配置面板文件,并在 ComUtils.ts 中注册枚举、在 index.ts 中注册导出。当用户提到"大屏新增组件"、"自助大屏添加组件"、"screen 新增组件"、"添加大屏自定义组件"时使用此 skill。 |
组件位于:packages/nocode/src/screen/charts/coms/
每个组件对应一个子目录,包含:
MfXxx/
├── index.vue # 组件展示逻辑
├── MfXxxConfig.vue # 样式/配置面板(可选)
├── MfXxxDataConfig.vue # 数据配置面板(可选)
└── mfXxx.data.ts # 组件数据定义(必须)
文件:packages/nocode/src/screen/charts/coms/ComUtils.ts
在 ComType 枚举末尾追加新类型:
MfXxx = "MfXxx",
<!--
@description: [组件描述]
@author: mfish
@date: [日期]
-->
<template>
<div :style="containerStyle" v-on="commonEvents">
<!-- 组件内容 -->
</div>
</template>
<script setup lang="ts">
import { PropType } from "vue";
import { Chart, ChartContain } from "../../../common/Constants.ts";
import { useChartEventHandle } from "../../../common/ChartEventUtils.ts";
defineOptions({ name: "MfXxx" });
const props = defineProps({
chart: { type: Object as PropType<Chart>, required: true },
chartContain: { type: Object as PropType<ChartContain>, required: true }
});
const { commonEvents } = useChartEventHandle(props.chart);
</script>
<style scoped lang="less"></style>
关键约定:
defineOptions({ name: "MfXxx" }) name 必须与组件目录名一致chart: Chart 和 chartContain: ChartContainemit("eventHandler", e) 并在 useChartEventHandle 第三参数传入事件名数组getFontStyle(props.chart) 获取计算样式<!--
@description: [组件]配置
@author: mfish
@date: [日期]
-->
<template>
<StyleConfig :class="prefixCls">
<slot></slot>
<!-- 配置项 -->
</StyleConfig>
</template>
<script setup lang="ts">
import { useDesign } from "@mfish/core/hooks";
import { useScreenEditStore } from "@nocode/stores";
import StyleConfig from "../../../frame/FrameConfig/BaseConfig/StyleConfig.vue";
const screenEditStore = useScreenEditStore();
const { prefixCls } = useDesign("xxx-config");
</script>
<style scoped lang="less">
@prefix-cls: ~"@{namespace}-xxx-config";
@import "../../../common/index";
</style>
常用配置子组件:
<TitleConfig /> — 文字样式(字体/大小/颜色/对齐)<MfishColorPicker /> — 颜色选择器<IconPicker /> — 图标选择<AInput /> — 文本输入<ACheckbox /> — 复选框<ARadioGroup /> + <ARadioButton /> — 单选组通过 screenEditStore.getCurConfigComponent.chart.options.xxx 读写配置,通过 screenEditStore.getCurConfigComponent.chart.data.dataSet.xxx 读写数据。
数据驱动组件(需要绑定 API 数据)才需要此文件。可参考 MfDataTag/MfDataTagDataConfig.vue。
这是最核心的注册文件:
import { createAsyncComponent } from "@mfish/core/utils/factory/CreateAsyncComponent";
import { cloneDeep } from "lodash-es";
import { Chart, MfComponent } from "../../../common/Constants.ts";
import { comConfigDisplay, ComponentData, ComType, DisplayConfig } from "../ComUtils.ts";
import { shallowRef } from "vue";
/**
* @description: [组件描述]
* @author: mfish
* @date: [日期]
*/
function mfXxxCreate(chart: MfComponent) {
chart.chart.data.dataSet = cloneDeep(mfXxxData.defaultData);
chart.chart.data.headers = mfXxxData.defaultHeaders && mfXxxData.defaultHeaders();
chart.chart.data.limit = 1;
chart.chart.data.maxLimit = 1;
chart.chartContain.dropInfo.width = 200; // 初始宽度(像素)
chart.chartContain.dropInfo.height = 100; // 初始高度(像素)
return chart;
}
const getConfig = () => {
const config = cloneDeep(comConfigDisplay) as DisplayConfig;
// 不需要数据配置时:config.data.show = false;
config.style.payload.component = shallowRef(
createAsyncComponent(() => import("./MfXxxConfig.vue"), {
loading: true,
size: "large"
})
);
// 有数据配置时:
// config.data.payload.component = shallowRef(
// createAsyncComponent(() => import("./MfXxxDataConfig.vue"), { loading: true, size: "large" })
// );
return config;
};
const mfXxxData: ComponentData = {
type: ComType.MfXxx,
component: createAsyncComponent(() => import("./index.vue"), { loading: true }),
create: mfXxxCreate,
config: getConfig(),
defaultData: { /* 静态默认数据 */ },
defaultHeaders: () => {
return cloneDeep({
fieldName: { colName: "fieldName", dataType: "string", rename: "字段名" }
});
},
initData: (chart: Chart, data?: any) => {
// 处理动态数据加载逻辑,静态组件直接留空 () => {}
},
// 可选:自定义事件
customEvents: [{ name: "事件名", value: "eventKey" }]
};
export default mfXxxData;
关键说明:
type 必须与 ComType 枚举值匹配create 中设置组件初始宽高和默认数据config.data.show = false 表示不显示数据配置 TabinitData: () => {} 即可initData 中解析 API 返回数据并写入 chart.data.dataSet如果组件需要被其他地方直接 import 使用(如 MfCombine、MfTag),在 index.ts 中添加:
export { default as MfXxx } from "../../charts/coms/MfXxx/index.vue";
注意:
.data.ts文件通过import.meta.glob("./**/*.data.ts")自动扫描注册,无需手动在index.ts中添加。
| 模式 | 参考组件 | 特征 |
|---|---|---|
| 纯静态文本/标签 | MfTag | data.show=false,initData: ()=>{} |
| 静态+可交互按钮 | MfButton | data.show=false,含 customEvents |
| 动态数据驱动 | MfDataTag、MfScrollTable | 有 DataConfig.vue,initData 解析数据 |
| ECharts 图表 | MfBar、MfLine | 使用 useEchartsData(),含 series/grid 配置 |
| DataV 装饰 | MfBorder*、MfDecoration* | 无数据,样式配置简单 |
- [ ] Step 1: ComUtils.ts 枚举中添加 MfXxx = "MfXxx"
- [ ] Step 2: 创建 MfXxx/index.vue
- [ ] Step 3: 创建 MfXxx/MfXxxConfig.vue(如有样式配置)
- [ ] Step 4: 创建 MfXxx/MfXxxDataConfig.vue(如有数据配置)
- [ ] Step 5: 创建 MfXxx/mfXxx.data.ts
- [ ] Step 6: index.ts 添加导出(如需全局引用)
- [ ] 验证:ComType.MfXxx 枚举值与 mfXxx.data.ts 中 type 一致
- [ ] 验证:组件 defineOptions.name 与目录名一致