本文将讲解如何通过自定义,实现锚点组件。这个锚点组件会根据界面设计器拖入的分组,动态解析出锚点。
实现路径
整体的实现思路是界面设计器拖个容器类的组件(这里以选项卡为例),自定义这个选项卡,往选项卡里拖拽的每个分组,每个锚点的名称是分组的标题。
1. 界面设计器拖出页面
我们界面设计器拖个选项卡组件,然后在选项页里拖拽任意多个分组。完成后点击右上角九宫格,选中选项卡,填入组件 api
名称,作用是把选项卡切换成我们自定义的锚点分组组件,这里的 api
名称和自定义组件的 widget
对应。最后发布页面,并绑定菜单。
2. 组件实现
widget
组件重写了选项卡,核心函数 renderGroups
,通过 DslRender.render
方法渲染界面设计器拖拽的分组。
import { BasePackWidget, DslDefinition, DslRender, SPI, Widget } from '@oinone/kunlun-dependencies';
import TabsParseGroup from './TabsParseGroup.vue';
function fetchGroupChildren(widgets?: DslDefinition[], level = 1): DslDefinition[] {
if (!widgets) {
return [];
}
const children: DslDefinition[] = [];
for (const widget of widgets) {
if (widget.widget === 'group') {
children.push(widget);
} else if (level >= 1) {
fetchGroupChildren(widget.widgets, level - 1).forEach((child) => children.push(child));
}
}
return children;
}
@SPI.ClassFactory(
BasePackWidget.Token({
widget: 'TabsParseGroup'
})
)
export class TabsParseGroupWidget extends BasePackWidget {
public initialize(props) {
super.initialize(props);
this.setComponent(TabsParseGroup);
return this;
}
// 获取分组的子元素
public get groupChildren(): DslDefinition[] {
return fetchGroupChildren(this.template?.widgets);
}
@Widget.Reactive()
public get groupTitles() {
return this.groupChildren.map((group) => group.title);
}
// 根据容器子元素渲染左侧
@Widget.Method()
public renderGroups() {
if (this.groupChildren && this.groupChildren.length) {
return this.groupChildren.map((group) => DslRender.render(group));
}
}
}
vue组件核心内容是用component :is
属性,渲染出配置的分组组件
<template>
<div class="TabsParseGroup">
<a-anchor :affix="false">
<a-anchor-link v-for="(item, index) in groupTitles" :href="`#default-group-${index}`" :title="item" />
</a-anchor>
<div v-for="(item, index) in groupComponents" :id="`default-group-${index}`">
<component :is="item" />
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue';
export default defineComponent({
name: 'TabsParseGroup',
components: {},
props: {
renderGroups: {
type: Function
},
groupTitles: {
type: Array as PropType<string[]>
}
},
setup(props) {
const groupComponents = computed(() => props.renderGroups?.());
return {
groupComponents
};
}
});
</script>
<style lang="scss">
.TabsParseGroup > .ant-anchor-wrapper > .ant-anchor {
display: flex;
}
</style>
3. 效果
Oinone社区 作者:银时原创文章,如若转载,请注明出处:https://doc.oinone.top/other/21349.html
访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验