Vue拖拽排序

文章展示了如何使用Vue.js来创建一个可拖放排序的列表,通过在li标签上应用draggable属性和绑定dragstart、drop、dragover事件,结合数组的splice方法实现元素的移动,从而达到动态调整列表顺序的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


这是渲染列表要用到的数组

linkData: [
  {name:'百度',url:'wwww.baidu.com',description:'baidu'},
  {name:'腾讯网',url:'wwww.qq.com',description:'tencent'},
  {name:'新浪微博',url:'https://www.weibo.com/',description:'weibo'},
  {name:'今日头条',url:'https://www.toutiao.com/',description:'bytedance'},
  {name:'哔哩哔哩',url:'https://www.bilibili.com/',description:'bilibili'}
]

渲染后的效果图:

 

在需 循环渲染的li 标签上 加上draggable=”true” 使li 标签可以被拖放,然后加上 @dragstart=”drag($event,index)”

    <li class="li_row" v-for="(item,index) in linkData " :key=index draggable="true"
                @dragstart="drag($event,index)" @drop="drop($event,index)" @dragover='allowDrop($event)'>
              <div class="li_item order">{{index+1}}</div>
              <div class="li_item title"><input v-model.trim="item.name" type="text" placeholder="请输入站点名称"></div>
              <div class="li_item url"><input v-model.trim="item.url" type="text"
                                              placeholder="链接需加上 http:// 或 https://">
              </div>
              <div class="li_item description"><input v-model.trim="item.description" type="text" placeholder="请输入描述">
              </div>
              <div class="li_item option">
                <el-button type="text" @click="deleteLink(index)">删除</el-button>
              </div>
            </li>

dragstart drop  dragover 这三个事件 绑定的方法 这样写:

 drag(event, index) {
        event.dataTransfer.setData('index', index);
      },
      drop(event, index) {
        event.preventDefault();
        let startIndex = parseInt(event.dataTransfer.getData('index'));
        let currentIndex = parseInt(index);
        console.log("start", startIndex);
        console.log("drop", currentIndex);
 
        if (startIndex - currentIndex > 0) {
 
          console.log("要拖拽的元素的索引 大于 当前位置的元素的索引");
          this.linkData.splice(currentIndex, 0, this.linkData[startIndex]);
          console.log("删除" + startIndex + 1);
          this.linkData.splice(startIndex + 1, 1)
 
        } else if (startIndex - currentIndex < 0) {
 
          console.log("要拖拽的元素的索引  小于 当前位置的元素的索引");
          this.linkData.splice(currentIndex + 1, 0, this.linkData[startIndex]);
          this.linkData.splice(startIndex, 1)
 
        } else {
          console.log("什么也不用做");
        }
 
 
      },
      allowDrop(event) {
        event.preventDefault();
      }

具体的这三个事件的用法在w3cschool 有讲,,   拖拽 li 标签,我们实际上是 操作的linkData 数组,利用数组的 splice方法 删除 添加元素,从而实现对数组的拖拽排序. 因为vue angular 等框架是数据驱动视图,数组变化了,界面也会变化.

效果:

 

### Vue.js实现拖拽排序的方法 #### 原生 HTML5 拖拽 API 和 Vue 的结合 通过原生 HTML5 拖拽 API,可以手动实现拖拽排序功能。这种方法不需要额外依赖第三方库,适合对性能有较高要求或者希望深入理解底层机制的开发者。 以下是基于原生 HTML5 拖拽 API 的简单示例: ```html <template> <div class="draggable-list"> <ul @dragstart="handleDragStart" @dragover.prevent @drop="handleDrop"> <li v-for="(item, index) in items" :key="index" draggable="true">{{ item }}</li> </ul> </div> </template> <script> export default { data() { return { items: ["Item 1", "Item 2", "Item 3"], }; }, methods: { handleDragStart(event) { event.dataTransfer.setData("text/plain", event.target.index); }, handleDrop(event) { const fromIndex = parseInt(event.dataTransfer.getData("text/plain")); const toIndex = Array.from(event.target.parentElement.children).indexOf( event.target ); this.items.splice(toIndex, 0, this.items.splice(fromIndex, 1)[0]); }, }, }; </script> ``` 此代码展示了如何使用 `@dragstart`、`@dragover.prevent` 和 `@drop` 来处理拖拽事件并更新数据列表[^1]。 --- #### 利用 vue-draggable-next 插件简化开发 对于更复杂的场景,推荐使用 `vue-draggable-next` 插件,它是 Vuedraggable 库的一个维护分支,支持 Vue 3 并提供了简洁易用的接口。 安装插件: ```bash npm install vue-draggable-next ``` 以下是一个完整的示例代码片段: ```html <template> <div> <h3>可拖拽列表</h3> <draggable v-model="items" tag="ul" item-key="id"> <template #item="{ element }"> <li>{{ element.name }}</li> </template> </draggable> </div> </template> <script> import draggable from "vue-draggable-next"; export default { components: { draggable }, data() { return { items: [ { id: 1, name: "Item A" }, { id: 2, name: "Item B" }, { id: 3, name: "Item C" }, ], }; }, }; </script> ``` 上述代码中,`v-model` 绑定了一个数组变量 `items`,并通过 `tag` 属性指定渲染为 `<ul>` 元素。每个子项由 `#item` 插槽定义[^1]。 --- #### 封装表单拖拽逻辑 如果需要进一步扩展功能,比如将拖拽行为封装到工具函数中,则可以通过引入自定义模块完成。例如,在 TypeScript 环境下,可以这样操作: ```typescript // utils/sortable.ts import Sortable from 'sortablejs'; export function enableRowDrop(targetElement: HTMLElement): void { new Sortable(targetElement, { animation: 150, onEnd({ oldIndex, newIndex }) { console.log('Moved', oldIndex, 'to', newIndex); }, }); } ``` 在组件中调用该方法时,需确保目标 DOM 已经挂载完毕[^2]。 ```javascript onMounted(() => { nextTick(() => { enableRowDrop(document.querySelector('.draggable-container') as HTMLElement); }); }); ``` --- ### 总结 无论是采用原生 HTML5 拖拽 API 还是借助成熟的第三方库(如 `vue-draggable-next`),都可以高效地实现Vue.js 中的拖拽排序功能。具体选择取决于项目的复杂度和个人偏好。 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值