vue-draggable跨iframe拖拽

发布时间 2023-08-23 09:47:57作者: fight139

环境

  1. vue3
  2. "vuedraggable": "^4.1.0"

物料区

<draggable
      class="dragArea list-group components-draggable"
      :list="material"
      :group="{ name: 'formGroup', pull: 'clone', put: false }"
      item-key="name"
      ghost-class="ghost"
      :sort="false"
      :clone="cloneComponent"
      draggable=".components-item"
  >
    <template #item="{ element }">
      <div class="components-item m-1"
          style="height: 30px; padding: 10px; border: 1px solid; margin: 5px"
      >
        <div class="components-body">
          <span class="truncate">{{ element.name }}</span>
        </div>
      </div>
    </template>
  </draggable>

预览区


  <PreviewIframe>
    <draggable
        class="dragArea list-group components-draggable"
        :list="targetSource"
        group="formGroup"
        itemKey="id"
        item-key="name"
        ghost-class="ghost"
        :clone="cloneComponent"
        draggable=".components-item"
    >
      <template #item="{ element }">
        <div class="components-item m-1"
            style="height: 30px; padding: 10px; border: 1px solid; margin: 5px"
        >
          <div class="components-body">
            <span class="truncate">{{ element.name }}</span>
          </div>
        </div>
      </template>
    </draggable>
  </PreviewIframe>

iframe

<style lang="css">
iframe {
  width: 100%;
  height: 500px;
  border: 1px solid red;
  padding: 25px;
}
</style>

<script>
import { createApp, createVNode, h } from 'vue'

export default {
  render() {
    return h("iframe", {
      onload: () => {
        console.log(this.$el)
      },
    });
  },
  mounted() {
    this.renderChildren();
    this.$el.contentDocument.body.ondrop = function (event) {
      event.preventDefault();
      event.stopPropagation();
    };
  },
  data() {
    return {
      awaitingEdit: false,
    };
  },
  methods: {
    renderChildren() {
      const body = this.$el.contentDocument.body;
      const el = document.createElement('div')
      body.appendChild(el);

      const that = this;
      const previewApp = createApp({
        name: "previewApp",
        render() {
          return h("div", {
            class: "preview",
            style: "height: 100vh"
          }, that.$slots);
        },
      });
      previewApp.mount(el);
    },
  },
};
</script>