自定义交互面板

可以通过definePanelMaker这个工具函数自定义交互面板资源。

定义面板

一个最简单的交互面板如下:

// SimplePanelMaker.ts
import definePanelMaker from '@/utils/definePanelMaker';
import { defineComponent, h } from "vue";

export default definePanelMaker({
    name: "简单面板",
    pkg: "test-pkg",
    defaultSplitLayoutPaneName: "right",
    make: () => defineComponent({
        render: () => h(
            'div',
            '我是一个简单面板'
        )
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

打开示例页面-自定义交互面板,可以在最下方的资源面板中找到新增加简单面板,点击简单面板,会看到面板在右侧被打开。可以通过defaultSplitLayoutPaneName来控制面板被打开的位置,有leftcenterrightbottom

自定义编辑器

可以自定义编辑器来更好辅助组件逻辑的属性配置,

颜色选择器面板

以自定义一个颜色选择器为例

// ColorPanel.vue
<template>
    <template v-if="config">
        <input type="color" v-model="colorString" />
    </template>
    <template v-else>请选择组件</template>
</template>
<script setup lang="ts">
import { useComponentSelected, ICookEditorState } from 'vue-cook';
import { computed, inject } from 'vue';
const cookEditorState = inject<ICookEditorState>('cookEditorState') as ICookEditorState
const selectedComponent = useComponentSelected(cookEditorState).get()
const colorString = computed({
    get: () => config.value?.props?.color,
    set: (value) => {
        if (config.value) {
            config.value.props = config.value.props || {}
            config.value.props.color = value || ""
        }
    }
})
const config = computed(() => {
    return selectedComponent.value?.component
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

创建一个带颜色配置的按钮组件

// Button.vue
<template>
    <button class="color-btn">我是可以配置颜色的按钮</button>
</template>
<script lang="ts" setup>
defineProps({
    color: String
})
</script>
<style lang="less">
.color-btn {
    color: v-bind(color);
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ButtonMaker.ts
import { defineComponentMaker } from 'vue-cook'
import Button from "./Button.vue";
export default defineComponentMaker({
    name: "按钮",
    pkg: "test-pkg",
    makePropOptions: () => ["color"],
    make: () => Button
})
1
2
3
4
5
6
7
8
9

打开示例页面-自定义颜色编辑器,按照以下步骤,使用此面板

  • 创建一个带按钮的页面
  • 从资源面板中打开颜色选择器面板
  • 选中按钮
  • 在颜色选择器面板中选取颜色,可以看到按钮的颜色发生了改变

组件拖拽添加面板

VueCook提供了<component-dragger>,可以很方便的实现组件拖拽添加这个功能

// ComponentDraggerPanel.vue
<template>
    <template v-if="config">
        <div v-for="slotOption in slotOptions" style="margin-bottom: 10px;">
            <div>{{ slotOption }}</div>
            <component-dragger @drop="handleComponentDrop($event, slotOption)">拖拽组件到此处添加</component-dragger>
            <div v-for="componentConfig in getSlotData(slotOption)">
                <div style="margin-bottom:3px;">
                    <div>uid:{{ componentConfig.uid }}</div>
                    <div>name:{{ componentConfig.name }}</div>
                    <button @click="del(slotOption, componentConfig)">删除</button>
                </div>
            </div>
        </div>
    </template>
    <template v-else>请选择组件</template>
</template>
<script setup lang="ts">
import { useComponentSelected, ICookEditorState, ComponentDragger, useSlotOptions, IComponentConfig, addComponentConfig, removeComponentConfig } from 'vue-cook';
import { computed, inject } from 'vue';
const cookEditorState = inject<ICookEditorState>('cookEditorState') as ICookEditorState
const selectedComponent = useComponentSelected(cookEditorState).get()
const config = computed(() => {
    return selectedComponent.value?.component
})
const slotOptions = useSlotOptions(cookEditorState, config)
const del = (slotName: string, componentConfig: IComponentConfig) => {
    if (config.value) {
        removeComponentConfig(config.value, componentConfig.uid, slotName)
    }
}
const handleComponentDrop = (componentConfig: IComponentConfig, slotName: string) => {
    if (config.value) {
        addComponentConfig(config.value, componentConfig, slotName)
    }
}
const getSlotData = (slotName: string) => {
    return config.value?.slots?.[slotName] || []
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

打开示例页面-自定义组件拖拽添加面板,按照以下步骤,使用此面板

  • 创建一个带按钮的页面,选中按钮
  • 从资源面板中打开组件拖拽添加面板
  • 可以看到它识别到了按钮组件拥有的插槽配置,并且每个插槽配置后面都带了一个框,上面写着拖拽组件到此处添加
  • 将资源面板中的emoji图标组件拖入,可以看到图标正常显示在按钮组件上
  • 点击删除按钮可以将添加的图标组件删除

逻辑拖拽添加面板

VueCook提供了<logic-dragger>,可以很方便的实现逻辑拖拽添加这个功能

// ComponentDraggerPanel.vue
<template>
    <template v-if="config">
        <logic-dragger @drop="handleLogicDrop($event)">fetch:拖拽逻辑到此处添加</logic-dragger>
    </template>
    <template v-else>请选择组件</template>
</template>
<script setup lang="ts">
import { useComponentSelected, ICookEditorState, LogicDragger, ILogicConfig, } from 'vue-cook';
import { computed, inject } from 'vue';
const cookEditorState = inject<ICookEditorState>('cookEditorState') as ICookEditorState
const selectedComponent = useComponentSelected(cookEditorState).get()
const config = computed(() => {
    return selectedComponent.value?.component
})
const handleLogicDrop = (logicConfig: ILogicConfig) => {
    const configValue = config.value;
    if (!configValue) {
        return;
    };
    configValue.props = configValue?.props || {}
    configValue.props["fetch"] = JSON.stringify(logicConfig)
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

打开示例页面-自定义逻辑拖拽添加面板,按照以下步骤,使用此面板

  • 创建一个带表格的页面,选中表格组件
  • 从资源面板中打开逻辑拖拽添加面板
  • 可以看到它显示了一个框,上面写着fetch:拖拽逻辑到此处添加
  • 将资源面板中的fetch逻辑拖入,页面中的表格组件的按钮文字变成了点我获取数据
  • 关闭选中模式,点击按钮,稍等片刻,可以看到数据加载成功

自定义资源面板

VueCook提供了<resource-maker>,可以很方便的在实现一个资源面板的同时,具有组件拖拽逻辑拖拽以及面板点击打开功能

// ResourcePanel.vue
<template>
    <div style="overflow: auto;height: 100%;">
        <resource-maker v-for="maker in makerList" :maker="maker"></resource-maker>
    </div>
</template>
<script setup lang="ts">
import { ResourceMaker, ICookEditorState } from 'vue-cook';
import { computed, inject } from 'vue';
const cookEditorState = inject<ICookEditorState>('cookEditorState') as ICookEditorState
const makerList = computed(() => {
    return cookEditorState.makerList
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

打开示例页面-自定义自定义资源面板,按照以下步骤,使用此面板

  • 创建一个新页面,选中新页面
  • 从资源面板中打开自定义资源面板,可以看到它将所有的资源都列了出来
  • 自定义资源面板拖拽表格组件到新页面的default插槽里,可以看到表格被正常添加
  • 选中页面中的表格组件,从自定义资源面板拖拽Fetch逻辑到它的fetch属性中,可以看到页面中的表格组件的按钮文字变成点我获取数据
  • 关闭选中模式,点击按钮,稍等片刻,可以看到数据加载成功

编程控制面板开关

有的时候需要通过代码来控制面板的开关,可以通过layoutAddTablayoutRemoveTab来打开和关闭面板

<template>
    <button @click="openPanel">打开面板</button>
    <button @click="closePanel">关闭自己</button>
</template>
<script setup lang="ts">
import { ICookEditorState, usePanelMaker, makeDefaultPanelConfig, layoutAddTab, layoutRemoveTab, IPanelConfig } from 'vue-cook';
import { inject, toRefs } from 'vue';
const props = defineProps({
    panelConfig: {
        type: Object as () => IPanelConfig,
        required: true
    }
})
const { panelConfig } = toRefs(props)
const cookEditorState = inject<ICookEditorState>('cookEditorState') as ICookEditorState
const openPanel = () => {
    const maker = usePanelMaker(cookEditorState, "开关面板", "test-pkg").value
    if (maker) {
        const panelConfig = makeDefaultPanelConfig(maker)
        layoutAddTab(cookEditorState, panelConfig, "right")
    }
}
const closePanel = () => {
    layoutRemoveTab(cookEditorState, panelConfig.value)
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

在PanelMaker中使用defineComponent传入Vue组件需要的props

import definePanelMaker from '@/utils/definePanelMaker';
import { defineComponent, h } from 'vue';
import TogglePanel from './TogglePanel.vue'
export default definePanelMaker({
    name: "开关面板",
    pkg: "test-pkg",
    defaultSplitLayoutPaneName: "right",
    make: (cookEditorState, panelConfig) => defineComponent({
        render: () => h(
            TogglePanel,
            {
                panelConfig
            }
        )
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

打开示例页面-编程控制面板开关,执行以下步骤,

  • 从资源面板中打开开关面板
  • 点击开关面板中的打开面板按钮,打开另一个面板
  • 点击开关面板中的关闭自身按钮,关闭面板自身

更多definePanelMaker的参数,参考definePanelMaker