Skip to content

插槽

该组件是低代码设计器中的占位与容器单元,本身不渲染任何业务 UI,而是作为可放置子组件的动态区域存在。它通常由其他容器类组件(如卡片、表单、布局容器等)在模板中通过代码插入,用于支持用户在指定位置拖拽或右键添加子组件。

核心作用

  • 提供组件插入点:在容器模板的特定位置声明一个 <插槽 />,使该区域成为合法的“投放区”;
  • 管理子组件列表:维护 slotChildren 数组,响应拖拽、添加、删除等操作;

属性配置

属性类型说明
栅格属性(如 span, offset, xs, sm 等)number | object仅当父组件为容器组件时生效(如布局容器、表单容器等)

使用方式

参考容器组件,容器类组件在实例化时会自动在对应位置生成插槽,单插槽可参考卡片容器多插槽可参考布局容器

卡片容器使用示例

创建插槽 重写组件定义的create方法,创建插槽

typescript
import Render from './index.render.vue'
import { LayoutJustifyOptions, WidgetDefine } from '../../../designer-editor.type'
import { createSlotItem, createWidgetInstanceDefault } from '../../../designer-editor.utils'
import { eventDefine, inputDefine, radioButtonDefine } from '../../../designer-editor.props'

const widget: WidgetDefine = {
  label: '卡片容器',
  icon: 'ep:postcard',
  render: (args) => () => {
    return <Render {...args} />
  },
  baseDesignerProps: [
    radioButtonDefine(
      {
        key: 'justify',
        label: '水平排列'
      },
      LayoutJustifyOptions.slice(0, 3),
      {
        _optionsOnlyIcon: true,
        _cancelable: true,
        _chunkSize: 3
      }
    ),
    radioButtonDefine(
      { key: 'shadow', label: '卡片阴影显示时机' },
      [
        {
          label: '显示',
          value: 'always'
        },
        {
          label: '不显示',
          value: 'never'
        },
        {
          label: '经过时显示',
          value: 'hover'
        }
      ],
      {
        _cancelable: true
      }
    )
  ],
  advDesignerProps: [
    inputDefine({ key: 'header', label: '卡片标题', bindable: true, defaultValue: '卡片标题' })
  ],
  create(editor, define) {
    const instance = createWidgetInstanceDefault(editor, define)
    //创建插槽
    instance.slots = [createSlotItem(editor)]
    return instance
  },
  events: [eventDefine('click', { type: 'mouse-function', label: '卡片点击' })]
}
export default widget

使用插槽 使用 useDefaultSlot() 检索默认插槽,使用 <WidgetItem> 组件渲染插槽内容

vue
<template>
  <el-card v-bind="cardAttrs">
    <el-row v-bind="rowAttrs">
      <el-col v-bind="colAttrs">
        <WidgetItem
          :editor="editor"
          :parent-widget="widget"
          :parent-render-context="widgetRenderContext"
          :widget="defaultSlotWidget"
          :options="widgetItemOptions"
        />
      </el-col>
    </el-row>
  </el-card>
</template>

<script setup lang="ts">
import { useElColPropAttrs, useWidget, type WidgetRenderProps } from '../../hooks'
import WidgetItem from '../../../components/WidgetItem.vue'
import { customWidgetOptions } from '../../../designer-editor.utils'

const widgetItemOptions = customWidgetOptions({ putable: true, selectable: true })

const props = defineProps<WidgetRenderProps>()

const { usePropAndEvent, useDefaultSlot } = useWidget(props)

const cardAttrs = computed(() => usePropAndEvent({ omit: ['justify'] }))

const defaultSlotWidget = computed(() => useDefaultSlot())

const colAttrs = computed(() => useElColPropAttrs(defaultSlotWidget.value))

const rowAttrs = computed(() => usePropAndEvent({ only: ['justify'] }))
</script>

注意:插槽组件不会出现在组件菜单中,仅能通过代码创建,确保其作为“基础设施”而非用户可随意拖入的业务组件。 该组件是低代码平台实现“任意嵌套”能力的关键基石,承载了整个组件树的动态组装逻辑。