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拷贝出来的
只是实现了关键部分,你可以根据自己的需要修改