一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情
🎉前言
本篇文章是我对拖拽列表功能的一些理解,实现一个简单的拖拽组件,来巩固一些知识点,如果能帮助到大家就更好😄
⭐️ 组件基本架构
vue 项目中 使用
npm install --seve sortablejs安装插件。sortablejs 官网
👨 父组件
接收一个 props 数组参数,用来记录 列表的条数,默认插槽 slot 用来存放 列表项。
// drag-wrap-test.vue
<template>
<div class="jc-drag-wrap-test" ref="wrapTest">
<slot></slot>
</div>
</template>
<script>
export default {
name: "jcDragWrapTest",
props: {
data: {
type: Array,
default: () => []
}
},
data () {
return {
list: []
}
}
};
</script>
👶 子组件
默认插槽 slot 用来存放 传进来的数据。CSS样式写好。
// drag-test-item.vue
<template>
<div class="jc-drag-test-item">
<span><slot></slot></span>
<p>view on Behance</p>
</div>
</template>
<script>
export default {
name: "jcDragTestItem",
};
</script>
<style lang="scss" scoped>
.jc-drag-test-item{
// ...样式代码省略
}
</style>
👪 实现效果
// 使用组件
<template>
<div>
<drag :data="tableData">
<drag-item v-for="item in tableData" :key="item.address">
{{ item.address }}
</drag-item>
</drag>
</div>
</template>
<script>
import drag from './drag-wrap-test/src/drag-wrap-test';
import dragItem from './drag-wrap-test/src/drag-test-item';
export default {
name: 'HelloWorld',
components: {
drag,
dragItem
},
data () {
return {
tableData: [
{
address: '深圳市南山区西丽 5 号线'
},
{
address: '深圳市南山区西丽 6 号线'
},
{
address: '深圳市南山区西丽 7 号线'
},
{
address: '深圳市南山区西丽 8 号线'
}
]
}
}
}
</script>
💫 实现拖拽
上述代码实现只是把基本样子写好,但是没有拖拽的功能,那我们借助 sortablejs 插件来试一下吧。
主要是在父组件里的实现:
// drag-wrap-test.vue
<template>
// ...省略代码
</template>
<script>
import { Sortable } from 'sortablejs';
export default {
// ...省略代码
mounted () {
let vm = this;
this.list = this.data;
// 调用Sortable 创建实例,传入两个参数(父元素,{配置项})
// 通过获取父元素的DOM,给里面的每个子元素添加配置项。
Sortable.create(this.$refs.wrapTest,{
animation: 150, // 过度效果,定义排序动画的时间
})
}
};
</script>
可以看到,拖拽的效果实现了,完结撒花~~ ✿✿ヽ(°▽°)ノ✿
但是这里有个问题,拖拽之后,如果页面刷新后,就会回到默认状态,怎么办?
那我们可以尝试给组件添加一个监听事件,如果你拖拽了列表,就会触发一个函数。
👀 拖拽事件监听
主要是利用 Sortablejs 里的 onEed()拖拽结束时触发的函数。
Sortable.create(this.$refs.wrapTest,{
animation: 150, // 过度效果,定义排序动画的时间
onEnd (event) {
vm.list = vm.data;
vm.list.splice(event.newIndex, 0, vm.list.splice(event.oldIndex, 1)[0]);
let newArr = vm.list.splice(0);
vm.list = [];
vm.$nextTick(() => {
vm.$emit('watchData', newArr);
})
}
})
onEnd() 函数中的 event 里面有被拖拽的列表项的一些监听属性,其实就是通过获取拖拽结束后新的数组,然后利用 $emit 事件把新的数组向父组件传递出去,在使用组件时,把新的数组重新赋值给 tableData 就好了。
修改一下 实现效果 中的代码:
<template>
<div>
<drag :data="tableData" @watchData="watchData">
<drag-item v-for="item in tableData" :key="item.address">
{{ item.address }}
</drag-item>
</drag>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
// ...省略代码
methods: {
watchData (data) {
console.log(data);
this.tableData = data;
}
}
}
</script>
我们来看一下最终的实现效果:
一个基本的拖拽列表组件就完成了~~ 真 · 完结撒花✿✿ヽ(°▽°)ノ✿
其实还有许多问题是没有考虑进去的,比如从这个列表拖拽到别的列表中呀,横向的拖拽呀等等,相信大家也能够自己实现,小弟我就不在这里班门弄斧了~~ 😙
👉 演示的源代码在这里 Gitee 链接。
✨总结
总的来说,实现该组件较为简单,比较麻烦的是,怎么拿到拖拽结束后新的数组列表。对于更为复杂的场景,我也是在慢慢探索呢。
以上我本次分享的全部内容~~
如果觉得文章写得不错,对你有所启发的,请不要吝啬 点个 赞 和 关注 并在 评论区 留下你宝贵的意见哦~~😃