Alfred-Skyblue / vue-draggable-plus

Universal Drag-and-Drop Component Supporting both Vue 3 and Vue 2
https://vue-draggable-plus.pages.dev/en/
MIT License
2.74k stars 105 forks source link

在使用<component>标签时嵌套内容拖动后控件会直接消失, 但是数据内容是正确的 #21

Closed moxcomic closed 1 year ago

moxcomic commented 1 year ago
// TestView.vue
<template>
  <div class="container">
    <VueDraggable
      class="left"
      :group="{ name: 'g1', pull: 'clone', put: false }"
      :clone="clone"
      :sort="false"
      animation="150"
      v-model="data"
    >
      <p v-for="(el, index) in data" :key="el.name + index">{{ el.name }}</p>
    </VueDraggable>
    <NestedDraggable v-model="list" class="right"></NestedDraggable>
  </div>
  <button @click="console.log(list)">log</button>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { VueDraggable } from 'vue-draggable-plus';
import NestedDraggable from './NestedComponent.vue';
import { v4 as uuidv4 } from 'uuid';
import data from './data';
import type { IComponentList } from './type';

const list = ref<IComponentList[]>([]);

const clone = (element: any) => {
  console.log('clone');
  let e = {
    key: uuidv4(),
    name: element.name,
    component: element.component,
    children: element.children
  };

  if (list.value.length === 0) {
    console.log('push');
    list.value.push(e);
    return;
  }

  return e;
};
</script>

<style lang="scss">
.container {
  display: flex;
  justify-content: space-between;
  height: 80vh;

  .left {
    width: 50%;
  }

  .right {
    width: 50%;
    background: green;
  }
}
</style>
// NestedComponent.vue
<template>
  <VueDraggable class="drag-area" v-model="modelValue" group="g1">
    <div v-for="(el, index) in modelValue" :key="el.name">
      <component :is="el.component" :index="index" v-model="modelValue"></component>
    </div>
  </VueDraggable>
</template>
<script setup lang="ts">
import { VueDraggable } from 'vue-draggable-plus';
import type { IComponentList } from './type';
// import TestComponent from './TestComponent.vue';

const modelValue = defineModel<IComponentList[]>({ required: true });
</script>
<style scoped>
.drag-area {
  min-height: 50px;
  outline: 1px dashed;
}
</style>
// TestComponent.vue
<template>
  <p>{{ modelValue[index].name }}</p>
  <NestedDraggable v-model="modelValue[index].children"></NestedDraggable>
  <br />
</template>

<script setup lang="ts">
import type { IComponentList } from './type';
import NestedDraggable from './NestedComponent.vue';

defineProps<{ index: number }>();

const modelValue = defineModel<IComponentList[]>({ required: true });
</script>
// data.ts
import type { IComponentList } from './type';

import TestComponentVue from './TestComponent.vue';

const data = [
  { key: '', name: '控件1', component: TestComponentVue },
  { key: '', name: '控件2', component: TestComponentVue },
  { key: '', name: '控件3', component: TestComponentVue, children: [{ key: '', name: '控件1', component: TestComponentVue }] },
  { key: '', name: '控件4', component: TestComponentVue },
  { key: '', name: '控件5', component: TestComponentVue }
];

export default data;
// type.ts
export interface IComponentList {
  key: string;
  name: string;
  component: any;
  children: IComponentList[];
}
image

如果将NestedComponent.vue中的<component :is="el.component" />改为<component :is="TestComponent" />就不会出现问题,不知道是什么特性引起的

liufeifeiholy commented 3 days ago

遇到同样问题,有解决的不