本文将讲解如何通过自定义,实现锚点组件。这个锚点组件会根据界面设计器拖入的分组,动态解析出锚点。 实现路径 整体的实现思路是界面设计器拖个容器类的组件(这里以选项卡为例),自定义这个选项卡,往选项卡里拖拽的每个分组,每个锚点的名称是分组的标题。 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…