mirror of
https://github.com/mathuo/dockview
synced 2025-09-04 08:26:28 +00:00
feat: make sure panel vue component be child of DockViewVue component
This commit is contained in:
parent
5b9dbdf57e
commit
73e5dc3571
@ -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,
|
||||
|
@ -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>
|
||||
|
13
packages/dockview-vue/src/dockview/teleport.vue
Normal file
13
packages/dockview-vue/src/dockview/teleport.vue
Normal 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>
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"exclude": ["src/**/__tests__/*", "src/**/*.cy.ts"],
|
||||
"compilerOptions": {
|
||||
"jsxImportSource": "vue",
|
||||
"composite": true,
|
||||
"baseUrl": "."
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user