简体中文
开发物料组件
在开发之前首先需要确认组件的定位,是属于 通用组件
还是 业务组件
亦或是其他大类。
再次要确定其小类,也就是属于 表单
还是 展示
还是其他小类。其对应关系如下
大致目录结构请参阅:packages/event-action
这里我们以 通用组件
-> 展示
中的 按钮
物料组件为例进行说明讲解
开始
牛搭采用的是 monorepo
架构来处理预览模块和 editor 共用物料组件的文件。在 packages
下的每一个目录都是一个单独的 npm 包。
注意
并不是 packages/*
下的每一个包都能够单独发布。
如 packages/event-action
就只能被使用了 vite 的包(如 packages/editor
)进行导入使用
根据上述说明的组件定位,现在进入 packages\library\src\components\generic\input\button
文件夹,这里就是存放 button
物料组件的位置
请注意,这里文件的存放方式。根据规范,需要按照如下要求进行存放
input
├── button
│ └── index.vue
└── textbox
└── index.vue
警告
不能像这样,将物料组件平铺在目录下
input
├── button.vue
└── textbox.vue
最简示例
在这里您可以选择使用 .vue
或者 .tsx
,这里以 .vue
为例
一个最简单的物料看起来是这样的:
<template>
<div class="wiget-button">
<van-button>按钮</van-button>
</div>
</template>
<script lang="ts">
export default {
name: 'WidgetButton',
}
</script>
<style lang="scss" scoped>
.wiget-button {
// tailwind 样式
@apply w-full;
}
</style>
请观察上面的代码,与开发中后台时候的组件有什么异同?
是的,并没有什么不同,这里开发与中后台的开发十分相似。只不过多了一些配置选项,下面我们一一进行讲解。
导出对象
下面是这个 button 物料组件 <script>
块中的简化
我们规定:
- 每一个物料组件都必须写
name
字段,并且所有物料组件都必须以Widget
开头 - 物料组件的相关信息定义需要调用
defineLibraryComponent
函数,然后对其返回值进行解构 props
写在defineComponent
的对象中,并且每一项定义都需要调用createLibraryComponentPropItem
函数
其他信息请参考下面的图片和代码
export default defineComponent({
...defineLibraryComponent({
// 组件名称
name: 'WidgetButton',
// 所处大类,这里是 `通用组件`
libraryName: LibraryPanelTabEnum.generics,
// 所属小类,这里是 `展示`
tabName: 'show',
// 在小类中的排序
order: 1,
// 在面板中显示的提示信息
libraryPanelShowDetail: {
title: '按钮',
// 左侧的图标组件
icon: () => (
<>
<ElIcon size={16}>
<i-ep-aim />
</ElIcon>
</>
),
},
// 提示信息 & 组件预览
tips: {
// 预览标题
title: '按钮',
// 预览描述
desc: '用来展示一个按钮,你可以配置不同的展示样式,配置不同的点击行为。',
// 右侧的预览组件,这里使用的是函数式组件
// 如果该图标组件您需要使用其生命周期功能
// 那么可以使用 defineComponent 再定义一个组件
// 并放置在和 `index.vue` 同级目录下
// 再将其导入并使用于此处
preview: () => (
<>
<Button>按钮jsx</Button>
<Button type="primary">按钮jsx</Button>
<Button type="success" plain>
按钮jsx
</Button>
</>
),
},
}),
props: {
// props 每一项都需要调用 createLibraryComponentPropItem 函数
title: createLibraryComponentPropItem({
// 显示在属性面板的设置名称
title: '按钮名称',
// 默认值,同 props 的默认值
default: '按钮',
// 属性面板应该展示哪种表单类型
formType: AttributePanelFormItemInputTypeEnum.input,
// 应该在属性面板的哪个 tab 中
belongToPanel: AttributePanelsEnum.generic,
}),
},
setup(props, { emit }) {},
})
完善组件功能
一个按钮,我们期待的是它能够响应响应我们的点击操作。不过响应事件的并不一定是按钮自身。所以确保物料组件自身只是 事件的发送者
a.k.a. 事件触发器
通过下面的例子您就能明白
信息
很常见的一个功能是:
- 点击按钮,触发 click
- 页面中的其他组件响应操作,比如轮播图切换下一页
<template>
<div>
<van-button @click="onClick" @dblclick="ondblClick">按钮</van-button>
</div>
</template>
<script lang="tsx">
enum EventTriggersEnum {
click = 'click',
doubleClick = 'doubleClick',
}
export default defineComponent({
...defineLibraryComponent({
name: 'WidgetButton',
// 其他配置...
// 声明该物料组件存在的事件触发器
eventTriggers: {
// 组件上 事件触发器的唯一标识符
// 这里我们强烈推荐您使用枚举作为键值
[EventTriggersEnum.click]: {
// 对该事件的描述
title: '点击',
},
[EventTriggersEnum.doubleClick]: {
title: '双击',
},
},
}),
// 其他配置...
/**
* 所有物料组件触发事件都用 `dispatchEvent`
* `CUSTOM_EVENT_EMIT_NAME` 是一个全局常量
* 其值为 `dispatchEvent`
*/
emits: [CUSTOM_EVENT_EMIT_NAME],
setup(props, { emit }) {
function onClick() {
// 激活 单击事件
// 至于谁来执行,这里不需要物料组件关系
emit(CUSTOM_EVENT_EMIT_NAME, 'click')
}
function ondblClick() {
// 激活 双击事件
emit(CUSTOM_EVENT_EMIT_NAME, 'doubleClick')
}
return {
onClick,
ondblClick,
}
},
})
</script>
结束
Congratulation!您已经掌握编写物料组件的基本方法,开始向丛林跟深处进发吧!