vue2 vuex 中使用 sortablejs 拖拽库

1.存在问题

在vue2 vuex 中直接使用 sortablejs 拖拽库会有bug

因为 sortablejs 会自动修改 html dom, 然后用户在 onUpdate 中修改数据后,vue会重新渲染.

2次修改dom 会导致dom顺序混乱(我遇到了这个问题)

2.使用vuedraggable 解决

存在问题:不能在嵌套循环中使用

npm i -S vuedraggable 安装

拷贝 Sortable.mini.js vuedraggable.umd.min.js 需要在 vue vuex 后面引入

<script type="text/javascript" src="/js/vue.js"></script>
<script type="text/javascript" src="/js/vuex.min.js"></script>
<script type="text/javascript" src="/js/Sortable.min.js"></script>
<script type="text/javascript" src="/js/vuedraggable.umd.min.js"></script>

(也可以补拷贝直接 import)

import vuedraggable from vuedraggable

Vue.component('vuedraggable', vuedraggable )

使用(这是vuex的例子)

<draggable
        v-model="myList"
        handle=".handle"
        @change="log"
      >
      <div v-for="element in myList" :key="element.id">{
   
   {element.name}}</div>
</draggable>


computed: {
    myList: {
        get() {
            return this.$store.state.myList
        },
        set(value) {
            this.$store.commit('updateList', value)
        }
    }
}

3.自己做一个组件包裹sortablejs  vuexdroggable.vue

这里我在 index.html 手动引入了 Sortable.min.js 所以不需要 import

<template>
  <div style="display: none"></div>
</template>

<script>
export default {
  name: 'vuexdroggable',
  props: ['length', 'id', 'index', 'draggable'],
  methods: {
    removeNode (node) {
      if (node.parentElement !== null) {
        node.parentElement.removeChild(node)
      }
    },
    insertNodeAt (fatherNode, node, position) {
      const refNode =
        position === 0
          ? fatherNode.children[0]
          : fatherNode.children[position - 1].nextSibling
      fatherNode.insertBefore(node, refNode)
    },
    onDragUpdate (evt) {
      this.removeNode(evt.item)
      this.insertNodeAt(evt.from, evt.item, evt.oldIndex)
      //自定义事件 onUpdate
      this.$emit('onUpdate', this.index, evt.oldIndex, evt.newIndex)
    },
  },
  mounted () {
    var that = this
    this._sortable = new Sortable(document.getElementById(this.id), {
      animation: 150,
      draggable: this.draggable,
      onUpdate: function (evt) {
        that.onDragUpdate(evt)
      }
    })
  },
  beforeDestroy: function beforeDestroy () {
    if (this._sortable !== undefined) this._sortable.destroy()
  },
}
</script>

<style scoped>

</style>
<div id="icons_kindex">
      <div class="iconsItem" v-for="(item,index) in icons_kindex"></div>
</div>
<vuexdroggable :length="icons_kindex.length" @onUpdate="update" id="icons_kindex" index="kindex" draggable=".iconsItem" ></vuexdroggable>




methods: {
    update(index, oldIndex, newIndex){
        console.log(index, oldIndex, newIndex)
        //this.$store.commit('updateList')
    },
}
//vuexdroggable 本身没有任何显示效果 只是为了调用 sortablejs ,需要写到 <div id="icons_kindex">的后面(保证这个div已经渲染完成)
//length 数组长度(可移动对象的长度)
//id document.getElementById(this.id) 包裹可移动div 的id
//index 回调的传递给回调函数 可以根据需要传递任意值
//draggable 可拖拽的div

注意代码的关键是 在onUpdate中 禁止了Sortablejs修改dom.

关键代码是从 vuedraggable拷贝出来的

扫描二维码关注公众号,回复: 16732563 查看本文章

只是实现了关键部分,你可以根据自己的需要修改

猜你喜欢

转载自blog.csdn.net/tangshangkui/article/details/130641796