两个树的拖拽合并处理-- vue-draggable

  const filterSameColor = (a) => {
    // 页面内不能有相同名称配色
    const all = colors.value.map(item => item.color_list)
    const allcolor = [].concat(...all)

    const list = a.color_list.filter(function (nitem) {
      return allcolor.every(function (oitem) {
        return nitem.color_name !== oitem.color_name || nitem.color_value !== oitem.color_value
      })
    })

    list.forEach(colorItem => {
      const maxIndex = methods.getNumber(allcolor, 'color_name', colorItem.color_name)
      // const name = colorItem.color_name.includes(i18n.t('msg.editor.colors.unname'))
      //   ? `${i18n.t('msg.editor.colors.unnameItem')}${padStart(maxIndex++, 2, '0')}`
      //   : colorItem.color_name
      const name = maxIndex.has ? `${colorItem.color_name}${maxIndex.pad}` : colorItem.color_name

      Object.assign(colorItem, {
        color_id: `@${new Date().getTime()}@`,
        color_key: `${pageColorKey}${randomId()}`,
        color_name: name
      })
    })

    return list
  }

  const importDrag = {
    // 拖动整个页面的配色合并事件
    page (evt) {
      if (colorCurrPageRef.value.targetDomElement.contains(evt.to)) {
        const newColorList = evt.item.__draggable_context.element?.page_color_list && cloneDeep(evt.item.__draggable_context.element.page_color_list)
        console.log(newColorList, 'newColorList')

        // 找到导入的所有文件名称
        const foldNames = colors.value.map(item => item.folder_name)
        console.log(foldNames, 'foldNames')
        const mapColors = cloneDeep(colors.value)
        newColorList.forEach(item => {
        // 有同名文件夹
          // if (foldNames.includes(item.folder_name)) {
          //   const sameFold = mapColors.find(f => f.folder_name === item.folder_name)
          //   item.color_list = filterSameColor(item, sameFold)
          //   sameFold.color_list.push(...item.color_list)
          // } else {
          //   mapColors.push(item)
          // }

          const sameFold = mapColors.find(f => f.folder_name === item.folder_name)
          item.color_list = filterSameColor(item, sameFold)
          if (sameFold) {
            // 存在同名文件夹往文件夹中添加,不存在往后追加文件夹
            sameFold.color_list.push(...item.color_list)
          } else {
            mapColors.push({ ...item, folder_id: `@${new Date().getTime() + random(0, 100)}@` })
          }
        })

        Object.assign(colors.value, mapColors)
        !isEmpty(mapColors) && hooks.onImportColors.exec()
      }
    },
    // 拖动某个文件夹的配色合并事件
    fold (_to, _from, curr) {
      // console.log(curr, '拖动某个文件夹的配色合并事件')
      const currFold = curr.__draggable_context.element
      // const currFold = [{ folder_id: 1010, folder_is_basic: 1, folder_name: '莫名其妙的文件夹', folder_type: 3, color_list: [{ color_id: '@1667979708255@', color_key: '--common-page-color-8i02eoor', color_name: '未命名颜色02', color_range: 2, color_value: '#ffff00' }] }]
      const sameNamefold = colors.value.find(item => item.folder_name === currFold.folder_name)
      // console.log(sameNamefold, 'sameNamefold')
      // if (!sameNamefold) { return 'clone' } // 没有同名文件夹直接拖入

      importDrag.foldEnd = () => {
        // 有同名文件夹合并里面不同的配色
        console.log(currFold, 'currFoldcurrFold')
        const curr = currFold ? cloneDeep(currFold) : {}
        curr.color_list = filterSameColor(curr, sameNamefold)
        if (sameNamefold) {
          sameNamefold.color_list.push(...curr.color_list)
        } else {
          colors.value.push({ ...curr, folder_id: `@${new Date().getTime() + random(0, 100)}@` })
        }

        !isEmpty(curr) && hooks.onImportColors.exec()
      }
      return false
    },
    // 拖动单个配色的配色合并事件
    item (to, _from, curr) {
      // console.log(curr, '拖动单个配色的配色合并事件')
      if (to.el.classList.contains('fold-content-panel')) {
        $('.fold-title').removeClass('red')
        $(to.el).parents('.fold-item').children('.fold-title').addClass('red')
        const currItem = curr.__draggable_context.element
        const targetItems = to.el.__draggable_component__.realList

        importDrag.itemEnd = (arg) => {
          console.log(arg, 'currItemcurrItemcurrItem')
          const curr = currItem ? cloneDeep(currItem) : {}

          const mers = filterSameColor({ color_list: [curr] }, { color_list: targetItems })
          targetItems?.[0]?.color_range !== COLORRANGTYPE.GLOBAL && targetItems.push(...mers)
          !isEmpty(mers) && hooks.onImportColors.exec()
        }
      }

      return false

      // const color
    }
    // unchooseFold () {

    // },
    // unchooseItem (...a) {
    //   console.log(a, 'unchooseItemunchooseItemunchooseItemunchooseItem')
    // }
  }

  // 导入面板里的拖拽属性
  const imports = reactive({
    pageDragAttr: {
      group: { name: 'page', pull: 'clone', put: false },
      sort: false,
      onEnd: importDrag.page
    },
    foldDragAttr: {
      group: { name: 'fold', pull: importDrag.fold, put: false },
      sort: false,
      onEnd: (...arg) => { importDrag.foldEnd?.(arg) }
      // onUnchoose: importDrag.unchooseFold
    },
    itemDragAttr: {
      group: {
        name: 'item',
        pull: importDrag.item,
        put: false
      },
      sort: false,
      onEnd: (...arg) => { importDrag.itemEnd?.(arg) }
      // onUnchoose: importDrag.unchooseItem
    }
  })
<div class="color-list-box element-list-box" >
              <el-scrollbar>
                {/* 只是为了导入页面颜色的拖拽事件可以执行拿到目标位置,写死的list */}
                <Draggable sort={false} group={{ name: 'page', pull: false, put: ['page'] }} list={[{ id: 0 }]}
                  class="color-curr-page"
                  ref={colorCurrPageRef}
                  v-slots={{
                    item: ({ element }) => state.data && <ColorListTree isEdit={true} data-id={ element.id }
                      data={state.data}
                    // foldDragAttr={state.foldDragAttr}
                    />
                  }}
                >
                </Draggable>
              </el-scrollbar>
            </div>

            {/* 导入配色面板 */}
            {state.importSwitch && <div class="editor-colors-import-panel" >
              <div class="color-input">
                <el-input
                  clearable
                  v-model={state.searchPageColor}
                  suffixIcon={state.searchPageColor.length > 0 ? '' : 'Search'}
                />
              </div>

              <el-scrollbar class='page-cont'>
                <el-collapse>
                  <Draggable {...imports.pageDragAttr} list={pageList.value.filter(item => item.id !== store.state.app.siteMain.currentDetail.merchant_page_detail.id)}
                    v-slots={{
                      item: ({ element: pa }) => (<div class="page-item">
                        {/* <el-dropdown popper-class="colors-import-popper" v-slots={{
                        dropdown: () => <ColorListTree isEdit={false} isImport={true}
                          data={pa.page_color_list}
                          foldDragAttr={imports.foldDragAttr}
                          itemDragAttr={imports.itemDragAttr}
                        />
                      }}>
                        <popover list={pa.page_title} />
                      </el-dropdown> */}

                        <el-collapse-item name={pa.id} v-slots={{
                          title: () => <popover list={pa.page_title} />
                        }}>
                          <el-scrollbar class="color-import-scroll">
                            <ColorListTree class="colors-import-popper dropdown-item" isEdit={false} isImport={true}
                              data={pa.page_color_list}
                              foldDragAttr={imports.foldDragAttr}
                              itemDragAttr={imports.itemDragAttr}
                            />
                          </el-scrollbar>
                        </el-collapse-item>
                      </div>)
                    }}
                  >
                  </Draggable>
                </el-collapse>
                {/* )} */}
              </el-scrollbar>
            </div>}
            {/* 导入配色面板 end */}

ColorListTree 里面的结构:

<Draggable group="fold" :list="colors" :sort="false" chosen-class="chosenClass" v-bind="foldDragAttr" :disabled="nameEdit.fold">
<template #item="{element: fold}" >
// ...
   <Draggable :list="fold.color_list" @dragstart="itemDragStart" @end="itemDragEnd" filter=".forbid" v-bind="state.itemDargOption(fold)" class="fold-content-panel" :disabled="nameEdit.item">
   // ...
   </Draggable >
 </template>
</Draggable>
const itemDragEnd = (e) => {
  state.draging = false
  $('.fold-title').removeClass('red')
  //  是导入的配色不触发
  if ($(e.from).parents('.editor-colors-import-panel').length) { return }
  editor.hooks.onMoveColor.exec(e.item.__draggable_context.element.color_name || '')
  if (drapData.currItem) {
    const index = drapData.fromItems.findIndex(item => item.color_id === drapData.currItem.color_id)
    drapData.fromItems.splice(index, 1)
    // drapData.fromItems = drapData.fromItems.filter(item => item.color_id !== drapData.currItem.color_id)
    drapData.targetItems.push(drapData.currItem)
  }

  drapData.fromItems = []
  drapData.targetItems = []
  drapData.currItem = null
}
const itemDragStart = () => {
  state.draging = true
}
const state = reactive({
  active: [],
  draging: false,
  itemDargOption: (fold) => {
    // 判断是不是站点配色文件夹
    const notSiteFold = fold.folder_type !== COLORFOLDTYPE.SITE
    const put = (to, from, curr) => {
      if (to.el.classList.contains('fold-content-panel')) {
        console.log(from, 'fromfromfromfromfrom')
        drapData.currItem = curr.__draggable_context.element
        drapData.targetItems = to.el.__draggable_component__.realList
        drapData.fromItems = from.el.__draggable_component__.realList
        $('.fold-title').removeClass('red')
        $(to.el).parents('.fold-item').children('.fold-title').addClass('red')
      }
      return false
    }

    return {
      group: { name: 'item', pull: notSiteFold, put },
      sort: notSiteFold,
      ...props.itemDragAttr
    }
  },
  comonColorStr: computed(() => {
    const str = editor.state.base.siteGlobalEdit ? 'component' : 'page'
    return i18n.t(`msg.editor.colors.${str}`)
  }),
  isGlobalColor: (item) => item.color_range === COLORRANGTYPE.GLOBAL
})
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值