feat: make sure panel vue component be child of DockViewVue component

This commit is contained in:
chuyuan.du 2024-07-31 18:05:32 +08:00
parent 5b9dbdf57e
commit 73e5dc3571
6 changed files with 72 additions and 15 deletions

View File

@ -1857,11 +1857,6 @@ export class DockviewComponent
throw new Error(`No panel with id ${sourceItemId}`);
}
if (sourceGroup.model.size === 0) {
// remove the group and do not set a new group as active
this.doRemoveGroup(sourceGroup, { skipActive: true });
}
this.movingLock(() =>
destinationGroup.model.openPanel(removedPanel, {
index: destinationIndex,
@ -1870,6 +1865,11 @@ export class DockviewComponent
);
this.doSetGroupAndPanelActive(destinationGroup);
if (sourceGroup.model.size === 0) {
// remove the group and do not set a new group as active
this.doRemoveGroup(sourceGroup, { skipActive: true });
}
this._onDidMovePanel.fire({
panel: removedPanel,
from: sourceGroup,

View File

@ -15,6 +15,8 @@ import {
onBeforeUnmount,
markRaw,
getCurrentInstance,
reactive,
mergeProps,
} from 'vue';
import {
VueHeaderActionsRenderer,
@ -22,7 +24,8 @@ import {
VueWatermarkRenderer,
findComponent,
} from '../utils';
import type { IDockviewVueProps, VueEvents } from './types';
import type { IDockviewVueProps, VNodeType, VueEvents } from './types';
import Tele from './teleport.vue'
function extractCoreOptions(props: IDockviewVueProps): DockviewOptions {
const coreOptions = (PROPERTY_KEYS as (keyof DockviewOptions)[]).reduce(
@ -174,8 +177,29 @@ onBeforeUnmount(() => {
instance.value.dispose();
}
});
const vnodes = reactive<VNodeType[]>([]);
defineExpose({
add(item: VNodeType) {
vnodes.push(item)
},
remove(key: symbol) {
const index = vnodes.findIndex(item => item.key === key);
if(index > -1) {
vnodes.splice(index, 1);
}
},
update(key: symbol, props: Record<string, any>) {
const item = vnodes.find(item => item.key === key);
if(item) {
item.props = mergeProps(item.props, props);
}
}
})
</script>
<template>
<div ref="el" />
<div ref="el" :="$attrs" />
<Tele :items="vnodes"/>
</template>

View File

@ -0,0 +1,13 @@
<script setup lang="ts">
import type { VNodeType } from './types';
const props = defineProps<{
items: VNodeType[]
}>();
</script>
<template>
<Teleport v-for="item in props.items" :key="item.key" :to="item.target">
<component :is="item.component" :=item.props></component>
</Teleport>
</template>

View File

@ -1,4 +1,5 @@
import { type DockviewOptions, type DockviewReadyEvent } from 'dockview-core';
import type { Component } from 'vue';
export interface VueProps {
watermarkComponent?: string;
@ -13,3 +14,10 @@ export type VueEvents = {
};
export type IDockviewVueProps = DockviewOptions & VueProps;
export type VNodeType = {
key: symbol;
component: Component;
props: any;
target: HTMLElement;
}

View File

@ -21,6 +21,7 @@ import {
cloneVNode,
type DefineComponent,
type ComponentInternalInstance,
markRaw,
} from 'vue';
export type ComponentInterface = ComponentOptionsBase<
@ -69,22 +70,32 @@ export function mountVueComponent<T extends Record<string, any>>(
props: T,
element: HTMLElement
) {
let vNode = createVNode(component, Object.freeze(props));
// let vNode = createVNode(component, Object.freeze(props));
vNode.appContext = parent.appContext;
// vNode.appContext = parent.appContext;
render(vNode, element);
// render(vNode, element);
let runningProps = props;
// let runningProps = props;
const key = Symbol();
parent.exposed!.add({
key,
component: markRaw(component),
target: markRaw(element),
props,
});
return {
update: (newProps: any) => {
runningProps = { ...props, ...newProps };
vNode = cloneVNode(vNode, runningProps);
render(vNode, element);
// runningProps = { ...props, ...newProps };
// vNode = cloneVNode(vNode, runningProps);
// render(vNode, element);
parent.exposed!.update(key, newProps);
},
dispose: () => {
render(null, element);
// render(null, element);
parent.exposed!.remove(key);
},
};
}

View File

@ -4,6 +4,7 @@
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*", "src/**/*.cy.ts"],
"compilerOptions": {
"jsxImportSource": "vue",
"composite": true,
"baseUrl": "."
}