Giter Site home page Giter Site logo

Comments (10)

yyman001 avatar yyman001 commented on June 1, 2024

又经过一次调试发现

handleMoved ({ index }) {
      this.lists.splice(index, 1)
      console.warn('1',new Date())
    },
    handleDrop (draggable) {
      console.warn('2',new Date())
      this.lists.splice(draggable.index, 0, draggable.item)
    }

原因,应该是插件设计的问题,
插入方法比删除方法执行还要早出发,所以导致了有重复键的出现(也有可能不同浏览器的渲染差异造成)
解决办法hack:
handleDrop延迟执行,避免把copy元素先插入,这样2个重复的元素是导致我们出bug的主要原因

//但如果拖拉动作过快,也会可能产生以上的bug,原因已经说了
    handleDrop (draggable) {

          setTimeout(()=>{
           // '延迟操作'
              this.lists.splice(draggable.index, 0, draggable.item)
           })
         //或者 使用 this.$nextTick 

    }

最终比较完美的解决办法
1.把handleDrop 传入的对象 缓存起来
2.直接在 handleMoved 函数里面 把 删除操作完成

    handleMoved (targetDraggable) {
      //删除元素操作
        this.lists.splice(targetDraggable.index, 1)
     //插入之前的旧元素,为了安全使用了$nextTick,当然你可以不要也没什么问题
        this.$nextTick(()=>{
          this.lists.splice(this.delDraggable.index, 0, this.delDraggable.item)
         })
    },
    handleDrop (draggable) {
     //缓存起来
      this.delDraggable = draggable;
}

from vddl.

hejianxian avatar hejianxian commented on June 1, 2024

@yyman001 抱歉,最近有点忙,我现在看一下。

from vddl.

hejianxian avatar hejianxian commented on June 1, 2024

这应该是用了最新版的Vue2而产生的问题,原本设计就是drop会比moved先触发,错误的提示是来自drop执行的时候,插入了一个和被拖动一样的元素。这个目前应该不会影响功能,或者先把Vue版本降一下。我暂时没有很好的解决方案,让我再想想。

from vddl.

yyman001 avatar yyman001 commented on June 1, 2024

@hejianxian 其他demo一样会触发这个错误的,但我看源码(修改module里面的源文件),也没法定位是哪个方法删除插入,项目需要用到这个nested.vue,这种嵌套性,就更难修正这个bug,现在我想看看能不能暂时修复下。

from vddl.

hejianxian avatar hejianxian commented on June 1, 2024

@yyman001 主要原因是因为在列表触发 drop 事件的时候,需要进行列表数据的插入操作,而插入的数据就是被拖动起来的那个,而这个数据此时还没有被删除,这样新插入的数据在key值上的确是重复的。这个感觉是 Vue 换成 Prxoy之后才出现的问题。

from vddl.

yyman001 avatar yyman001 commented on June 1, 2024

@hejianxian 确实是这样的,就是那个嵌套的例子和源码有些功能有点复杂,例如我写了个自定义的drop事件,会把拖拉的元素删除,并没有添加成功,这个要用到vuex,如果可以把删除和添加方法暴露的更清晰点就好了,可以让自己控制,但现在我改源码调试也没有办法调试得出具体在哪里写这个操作,想配合vuex,现在不懂怎么处理,好尴尬,能力太弱。

from vddl.

yyman001 avatar yyman001 commented on June 1, 2024

@hejianxian 先删再添加,又引发一个bug,就是拖拽,如果由下往上,插入的位置是正确的,如果从上向下拖,位置会+1,位置不正确。。。真是头疼

from vddl.

yyman001 avatar yyman001 commented on June 1, 2024

@hejianxian @awulkan
我又想到了另外一个方法,是这样的
1.在插入的数据的时候,用一个别的对象(B占位符对象)来替换这个一样的元素A副本,当然这个对象跟之前那些一样,除了key值外,防止报错
2.然后接着删除旧的复制元素A的本体
3.把占位符替换为原来的那个拖拽元素A副本
另外,我是想了另外一个办法,是拷贝那个list数组为fix-list,然后完成上面的fix操作,最后替换原来的那个list,但这个有个问题,就是没办法把整个数组替换?我翻阅了官网和网上一些资料都没找到。
具体代码

this.temp = null
this.placeholderObject = {'label':'placeholderObject'}
handleDrop(data) {
      console.log(':v-list: drop');
      const { index, list, item } = data;
      this.temp = data
     //1. 使用占位符对象
      list.splice(index, 0, this.placeholderObject);
    },
    handleMoved(item) {
      console.log(':v-draggable: moved');
      let vm = this
      const { index, list } = item;
      //拷贝数组
      const fix_list = list.concat()
    //key,用来查找占位符对象,如果找不到-1会把最后一个元素删了
      let _key = -1; 
     //修复前的数组
      console.warn('1-fix_list:', JSON.stringify(fix_list));
     //删除本
      list.splice(index, 1)
      fix_list.splice(index, 1)
      fix_list.forEach(function (item, key) {
        console.log(key,JSON.stringify(item) ,JSON.stringify(item) === JSON.stringify(vm.placeholderObject));
      //如果找到占位符对象记录key
        if(JSON.stringify(item) === JSON.stringify(vm.placeholderObject)){
          _key = key
//不在这里替换,会报错,具体原因不知道
        }
      });
      fix_list[_key] = this.temp.item
      //替换占位符对象
      this.$set(item.list,_key,this.temp.item)
     //修复后的数组
      console.warn('2-fix_list:', JSON.stringify(fix_list));
   //      item.list = fix_list 这个不是响应的,试图不会更新
    }

from vddl.

yyman001 avatar yyman001 commented on June 1, 2024

发现占位符getPlaceholderIndex()方法获取index好像不太正确。
最后更新方法:不清楚有时候拖拽会报key 1重复。。。

[SAVE_DATA] (state, destinationData) {
    console.log('目标index:', destinationData.index);
    state.destinationData.index = destinationData.index
    state.destinationData.item = destinationData.item
    state.destinationData.list = destinationData.list
    destinationData.list.splice(destinationData.index, 0, state.placeholderObject);
  },
[UPDATE_ITEM] (state, originItem){
    //1. 删除原数据
    originItem.list.splice(originItem.index, 1)

    //fix 计算占位符索引,同级拖拽由上往下,无法正确找到正确的索引(具体原因不清楚)
    let fixDestinationDataIndex = -1; //默认是未找到
    let placeholderObjectString = JSON.stringify(state.placeholderObject)

    state.destinationData.list.forEach(function (_item, key) {
      console.log(key, JSON.stringify(_item), JSON.stringify(_item) === placeholderObjectString);
      if (JSON.stringify(_item).indexOf(placeholderObjectString) > -1) {
        fixDestinationDataIndex = key
      }
    });
    console.log('修正查找目标的索引:', fixDestinationDataIndex);
    //2.删除占位符
    state.destinationData.list.splice(fixDestinationDataIndex, 1)

    //3.插入原数据
    state.destinationData.list.splice(fixDestinationDataIndex, 0, state.destinationData.item)

  }

from vddl.

boutell avatar boutell commented on June 1, 2024

+1. We get this warning, it's transitory I think, a moment later there are no duplicate keys anymore.

from vddl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.