Vue中使用Sortable:A和B拖拽交换位置之后,B和A又神奇得换回去了,但下面的数据确实已交换

参考:Vue中使用Sortable

1 问题

Vue中使用Sortable拖拽表头达到改变列的位置的效果,

想法:使用该组件进行拖拽列,但它不会切换原表头下的数据,因此:1、先拖拽,2、手动交换原先vue中的表头,达到切换表下方的数据顺序。

现象:A和B拖拽交换位置之后,B和A又神奇得换回去了,但下面的数据确实已交换。

2 原因

2.1 原DOM映射关系

表头虚拟DOM(vue) :[A,B]
表头真实DOM(html):[$A,$B]

2.2 操作

操作1,使用组件交换真实DOM:

[$B,$A]

操作2,代码中交换虚拟DOM:

[B,A]
[$B,$A]

2.3 操作解析

旧与操作2的”虚拟DOM“比较(sameVNode()):

旧:[ A,  B]
     ||  ||
新:[ B,  A]

因为两个虚拟DOM相同,则直接替换,替换关系如下图所示,即以新的虚拟DOM顺序为最新顺序,然后用新的”真实DOM“替换旧的,即:

旧:[ $A,  $B]
      ^    ^
      |    |
新:[ $B,  $A]

找到替换关系后,准备替换,而此时旧的里面,两个真实DOM的顺序,已经交换为[$B,$A],那么替换关系则变成:

旧:[ $B,  $A]
      ^    ^
       \  /
        \/
        /\
       /  \
新:[ $B,  $A]

最终的结果则变成:

[B,A]
[$A,$B]

3 解决方案

3.1 使两个虚拟DOM不相同

只要key不同,那么两个虚拟DOM就不相同,不相同后会怎样,则参考下方4附录

<div key="1"/>

3.2 还原拖拽操作

参考最上方的参考文档。

4 附录

在虚拟DOM(Virtual DOM)的概念中,有一个函数通常被称为sameVNode,用于判断两个虚拟DOM节点是否相同。如果sameVNode返回false,这意味着两个虚拟DOM节点不相同,可能会触发重新生成真实DOM节点。

虚拟DOM是一种在内存中维护的、与真实DOM结构相似的JavaScript对象树。它充当了真实DOM的轻量级副本,可以进行高效的比较和更新。当进行界面更新时,首先会比较新旧虚拟DOM树的节点,而不是直接操作真实DOM。这种比较可以在内存中快速完成,减少了直接操作真实DOM所带来的性能开销。

如果sameVNode返回false,这意味着两个虚拟DOM节点的类型不同,或者某些关键属性不同,需要进行更新。在这种情况下,通常的做法是:

删除旧虚拟DOM节点对应的真实DOM节点。
创建新的真实DOM节点,基于新虚拟DOM节点的描述。
将新的真实DOM节点插入到正确的位置。
这个过程称为“协调”(reconciliation),它确保虚拟DOM树与真实DOM树保持同步。

需要注意的是,不是所有情况下都需要重新生成真实DOM节点。例如,如果两个虚拟DOM节点的内容没有发生变化,但是属性发生了变化,可能只需要更新真实DOM节点的属性,而不需要替换整个节点。

总之,sameVNode返回false是虚拟DOM更新的一个关键标志,意味着需要对相应的真实DOM节点进行更新操作,但具体的更新方式会根据不同的情况而变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值